フィードフォースエンジニア Advent Calendar 2015 の2日目の記事です。
1日目の記事はCTOすーさんの feedforceアドベントカレンダー2015が始まります! でした。
普段から「SQL大好き」とか「SQL可愛い」とか言っているけど、ほんと SQL 可愛い。
最近、自分が SQL を勉強しはじめたくらいの頃のメモを見返すことがあったのだけれども、だいぶ初々しい感じだった。
まだ SQL のことをよく知らなくて「もっと仲良くなりたいのに、なかなか近づけない……!」というすれ違う少女漫画のような距離感で SQL と付き合っていたなあ。と遠い目になった。
今は SQL 可愛い (ほんと可愛い) と思ってるけど、あの頃よりは、少し……ほんの少しかもしれないし幻想かもしれないけど、仲良くなれたのかなあ。
なれてると良いなあ。
仲良くなるために何をやったかっていうのは、具体的には色々やった……と思うので、なかなかぱっとは言えないけど。
相手を知ろうとすることが、仲良くなる基本かもしれないなあ、とか思った。
SQL のことを知るためには、結局 RDB のこととか、設計のこととか、色々なことを知る必要があって。
そんな色々なことの積み重なりで SQL の仕事のやり方がわかるようになって。
そこからどう書いたら良いかもわかるようになってきた、という感じかも。
そんな、比喩過多で雑な SQL の話をします。
SQL 可愛いって、もう何度も言ってるけど SQL が可愛い理由は、なんといってもその健気さ。
例えば ORDER BY
って割とパフォーマンスに影響が出やすいのだけれども。
ORDER BY
って、指定されたカラムの比較を行う必要があるから。
ORDER BY
指定せずに LIMIT 10
する時と比べるとわかると思うけれども。
ORDER BY
なしの時には、単に適当に LIMIT
で指定された件数を SELECT
で持ってきたら良いってだけ。
今回の場合は 10 件見つかれば、そこで終わり。
10 件以上のレコードを見る必要はない。
だけど ORDER BY
した上で LIMIT 10
すると、最初の 10 件を見つけるために全レコードの ORDER BY
で指定されたカラムを見て比較しないといけない。
比較して、並べ替えて、ようやく最初の 10 件が見つかる。
例えばこの時、テーブルにレコードが 10_000 件あったら?
100_000 件だったら?
それ以上だったら?
よく考えたら全くその通りの話なんだけれども、初心者の頃の色々わかってなかった自分はこういうところまで頭がまわってなかった。
ちなみに ORDER BY
のパフォーマンス対策としてはインデックスが一般的だけれども。
それもデータの件数や偏り具合によっては効果が薄かったりする。
並べ替えの対象を減らせるならそれは効果がある、かも?
SQL のパフォーマンスチューニングについて調べると、
「JOIN
は重い」
「サブクエリは使うな」
ってよく聞く。
今はどうかな。自分が初心者の頃は、そういう記事をいっぱい見た。
それも、中で何が起こっているかがわかると、やみくもに「使っちゃ駄目」って思わなくても良くなる。
そもそも、なんで JOIN
やサブクエリが重くなるかっていったら ORDER BY
の時と同じ。
SQL に書かれた通り、その通りに、全部を、処理対象にするから。
例えば、FROM
に指定したテーブル A
のレコードが 10_000 件、LEFT OUTER JOIN
に指定したテーブル B
のレコードが 1_000 件あった場合を考える。
テーブル A
のレコード件数分、テーブル B
の対象レコードを探す処理が必要になる。
これは、最悪の場合 10_000_000 (= 10_000 * 1_000) レコード分の処理になる。
もっと件数が多かったら?
JOIN
は掛け合わせなので、元になる情報が大きければ大きいほど、その結果は膨れ上がる。
ON に指定するカラムにインデックスはってあれば多少はマシになるけど、掛け合わせた結果の多さはどうしようもない。
で。
JOIN
が遅い時、サブクエリを使うと速いことがある。
その頃の自分は「サブクエリは使わない方が良い」というのを鵜呑みにしていたので、その結果にびっくりしたことがある。
「サブクエリの遅さ」は何か、というと、サブクエリの SELECT
結果が仮のテーブルとして作られてしまうこと。
その仮のテーブルはメモリ上に、メモリが足りなければ実ファイルに、作られる。
当然、その分重くなる。
SELECT
の結果が大量ならなおさら。
だけれども。
サブクエリの SELECT
の結果が有限で、現実的な件数に収まるような場合には、JOIN
の掛け合わせよりも、サブクエリが仮のテーブルを作る方が仕事量少ない! ってことになる。
インデックス使うと大抵はやくなるけど、たまにかえって仕事を増やす結果になることもあるって話。
(最近は RDB が賢くなってそういうこともあまりないのかな、どうなんだろう)
インデックスを使って絞り込んだり並べ替えたりした後に、結果を返すためにレコード全体を取得するのだけれども。
その時に必要な情報というのは基本、あちこちに、ばらばらに、点在してしまっている。
その散らばった情報を集めてまわるのも、仕事のひとつ。
なので、仕事が増えた分だけ、結局時間がかかることになる。
みたいなこともあったりする。
ケースバイケースというか、いつも、必ず、うまくいく方法はなくて、毎回 SQL と向き合わないといけないのかもしれないなあ。
SQL 健気で可愛い。
NULL で困っちゃうところも可愛い。
うっかり色々仕事をさせると頑張りすぎちゃうので、ほどほどに。
仕事を押し付けすぎないようにすると、うまくお付き合いできそう。
って思ってる。
SQL ほんと可愛い。
さて、3日目の記事はFFエンジニアの可愛い担当 a-know の FF社のホワイトボードたちをご紹介します(੭ु ›ω‹ )੭ु⁾⁾です!