MySQLの基本的なSQLの評価順を日本語で表現してみる(1)


決め事として、

  • indexed_*** = インデックスが貼ってあるカラム
  • unindexed_*** = インデックスが貼ってないカラム

とする。

indexとは

MySQLのデータテーブルにもPostgreSQLと同じようなoidがレコードごとに存在し、indexとは、そのoidとカラムの値を対で持ったシンプルなテーブルみたいなものだと理解すればわかりやすい。
そのカラムだけを見て、どの行が該当するかを判断することができるため、検索負荷が非常に少なく済むのだ。

はじめに、シンプルなSQL

例えばこんなSQL。
SELECT COUNT(indexed_id) FROM sample_table WHERE indexed_column_1 = 1 AND unindex_column_2 > 2 AND indexed_column_3 = 3 ORDER BY indexed_id desc LIMIT 10;

どこにでもよくある文体だけど、これを日本語で表すと

  1. indexed_id のインデックスを参考に、実レコードの評価をする際のレコードの評価順を降順と定める
  2. インデックスを参考に indexed_column_1 = 1 を満たすレコードを全て特定する
  3. 上記までで特定した範囲で、最初に決めた評価順でunindex_column_2 > 2 を満たす実レコードを全て特定する
  4. 上記で抽出した実レコードから、インデックスを参考に indexed_column_3 = 3 の実レコードを全て抽出する
  5. 上記で抽出した実レコードから、最初に決めた評価順で先頭から探し、最大10件抽出する
  6. 特定したレコードのindexed_id の数を算出する

となる。

基礎条件:インデックスに乗ってないカラムのWHERE条件はできる限り後ろに

これを、こう書き換えると
SELECT COUNT(indexed_id) FROM sample_table WHERE indexed_column_1 = 1 AND indexed_column_3 = 3 AND unindex_column_2 > 2 ORDER BY indexed_id desc LIMIT 10;

こんな日本語になる。

  1. indexed_id のインデックスを参考に、実レコードの評価をする際のレコードの評価順を降順と定める
  2. 上記まででインデックスを参考に indexed_column_1 = 1 を満たすレコードを全て特定する
  3. 上記までで特定した範囲で、インデックスを参考に indexed_column_3 = 3 を満たすレコードを全て特定する
  4. 上記までで特定した範囲で、最初に決めた評価順でunindex_column_2 > 2 を満たすレコードを先頭から探し、最大10件特定する
  5. 特定したレコードのindexed_id の数を算出する

どちらが処理コストが少ないかは自明で、レコード数が多くなればなるほどその傾向は顕著になるのだ。


No Comments

Post a Comment