SQL・テストデータ
長いSQLの条件やJOINを読みやすく確認したい
使うツール
ログに出てきた長いSQLを読むとき、まず知りたいのは『何を取ろうとしているのか』です。横へ何度もスクロールしていると、ANDとORの間の括弧やJOINの条件を見落とします。SQL整形で段落のように構造を見せると、確認する順番を作れます。ただし、読みやすくすることと正しく動くことは別です。このツールはDBへ接続せず、SQLを実行もしません。
架空の注文SQLを、句ごとに分ける
SQL整形でPostgreSQLを選び、次の例を入れます。SELECT、FROM、LEFT JOIN、WHERE、ORDER BYが見つけやすくなり、キーワードは大文字で表示されます。まずSELECTで返す列、FROMで出発する表、JOINで結び付ける表、WHEREで残す行、ORDER BYで並べ方を読みます。説明用の架空の表名なので、実DBへ貼り付ける必要はありません。
select o.id,o.total,c.name from orders o left join customers c on c.id=o.customer_id where o.status='paid' and (o.total>=1000 or o.priority=true) order by o.id;整形結果を読むときは、元のSQLも残して比較します。大文字化や改行は、条件を訂正したことを意味しません。テーブルや列が存在するか、権限があるか、結果が何行になるかはDBの情報が必要です。この画面が成功しても、SQLの意味や実行可否まで検証済みと考えないでください。
ANDとORの間で、どこまで条件が掛かるか
例はpaidであり、かつ金額1000以上またはpriorityがtrue、という条件です。括弧を外すと、通常の優先順位ではpaidかつ1000以上、またはpriorityがtrueとなり、優先注文なら未払いでも含む形へ変わります。整形によって括弧が見やすくなっても、期待する業務条件まではツールに分かりません。少額のpaid、大額の未払い、priorityだけtrueなど、境界の架空行を紙に並べると違いを確認できます。
WHEREだけでなくJOINのONも別に読みます。LEFT JOINの右側の列をWHEREで必須条件にすると、結び付かなかった行が落ちる場合があります。『LEFT JOINだから左の行は必ず全部残る』と名前だけで決めないことが大切です。条件の位置を変える修正は単なる整形ではなく意味を変え得るため、このツールの作業と、SQLを書き換えるレビューを分けます。
方言を変えても、DB移行の変換にはならない
この画面はPostgreSQL、MySQL、SQLiteの方言を選べます。入力元の方言を選ぶのが基本です。MySQLの文をPostgreSQLとして整形しても、関数、型、引用符、日付処理まで互換な文へ翻訳されるわけではありません。対応しない文でエラーが出た場合、通る方言へ変えて成功表示だけを得るより、元のDBと構文を確認します。
ログにはSQL以外の時刻、識別子、処理時間が前後に付くこともあります。その場合はSQL本文の範囲を確かめてから入力します。文字列リテラル内の改行や引用符を、ログの飾りと間違えて削らないでください。実行時パラメーターが別の欄へ出ているなら、SQLと引数を混ぜて見た目だけの完全な文を作る前に、対応関係を読み取ります。
同じ名前の引数が二回出る場合
SQLプレースホルダー変換では、:idが二回ある文と、引数オブジェクトを別々に入力できます。:idをPostgreSQL形式へ変えると、同じ値を指す二箇所は両方$1になります。一方、?形式では出現位置ごとに引数が必要なので、対応表に同じ値が二回並びます。置換後のSQLだけをコピーし、引数の順番を古いままにしないようにします。
SELECT * FROM users WHERE id = :id OR manager_id = :id
Arguments: {"id":7}
PostgreSQL: id = $1 OR manager_id = $1
Question: id = ? OR manager_id = ? → [7, 7]この変換にも対応範囲があります。文字列やコメント内の記号を通常の引数とは分けますが、あらゆる方言固有構文を解析するDBエンジンではありません。特にPostgreSQLの?は演算子にもなるため、?を入力形式にする条件は制限されています。未対応の構文を含む大きな文は、利用するドライバーやDBの公式仕様でも確認してください。
読めた次に調べることを決める
行数が多すぎるなら条件やJOINの関係、値が違うなら引数やNULL、遅いなら実行計画やデータ量といったように、次の調査を分けます。整形ツールは実行時間、Index利用、ロックを測りません。読みやすくなったSQLだけを見て『速くなった』と判断することもできません。ここで得るのは、調査対象を見つけるための読みやすい文です。
共有するときは、実際の個人情報や秘密値を架空の値へ置き換え、条件の構造が変わっていないことを確認します。DBへ実行する工程は、このツールとは別の承認・検証が必要です。まず句と括弧を読み、次に引数との対応を確かめる。その順番なら、長い一行のSQLを見てすぐ実行するより、何を確認したいかを明確にできます。
見やすいSQLになったら、何行になるかを考える
JOINが見やすく分かれたら、一行の注文へ相手の表が何行対応するかを考えます。顧客が一件のつもりでも、結合キーが一意でなければ複数行へ増える可能性があります。整形ツールは表の定義やデータを読んでいないので、結果件数が想定どおりかを判定しません。重複行が出たとき、見た目を整えたSQLが原因というより、結合関係を読めるようになったことで原因を探せる状態になったと考えます。DISTINCTを足して隠す前に、どこで行が増える構造なのかを確認します。
LEFT JOINした表の列へWHEREで条件を付けると、結合相手がいない行を除外する場合があります。条件をONへ置くかWHEREへ置くかは、単なる見た目の移動ではありません。整形後に句の位置が読めるようになったら、残したい行がどの条件で除かれるかを具体例で考えます。このツールが条件を書き換えて正しい場所へ移してくれるわけではありません。架空の少数行を使って期待する結果を先に書き、実行環境での確認は権限と対象を限定した別作業として行います。
読みやすさが上がっても、クエリーが速くなるとは限りません。インデックス、行数、統計、実行計画はこの入力に含まれていないからです。『SQLを整形した』という変更と、『同じ結果を保ちながら実行を改善した』という変更を分けて報告します。後者を確かめたいなら、整形したSQLを調査の出発点にし、対象のDBで実行計画や実測を確認する必要があります。キーワードが大文字になったことや改行が増えたこと自体を、性能改善の根拠にはしません。