(ゴードンの答えは良いです。しかし、私は言いたいことがいくつかの異なるものを持っている...。)
SELECT ... WHERE unique_col = constant
- これはテーブルから(もしあれば)1行を読み込みます。 LIMIT 1
は、些細な解析時間以外の影響はありません。
SELECT ... WHERE non_uniq_col = constant
- これは、一致しない行が見つかるまで読み取ります。つまり、N行を読み込むためにN + 1行を読み込みます。この場合、LIMIT 1
はそれを止めるでしょう。今質問はパフォーマンスに関するものではありません(Nが小さい場合はあまり違いはありません)が、機能については(1行またはNが必要ですか?)
InnoDBでは、PRIMARY KEY
はデータで「クラスタ化」されており、暗黙的にはUNIQUE
です。それは上記の通りです。
セカンダリキーでは、追加のステップがあります。最初に、のインデックスBTreeの行が見つかりました(col=const
)。そのBTreeのリーフノードには、目的の行のPKがあります。余分なステップは、行を見つけるためにPKのBTreeをドリルダウンすることです。これはいくらか余分なコストがかかりますが、中小規模のテーブルではあまり心配する価値はありません。 (LIMIT 1
の問題は、まだ適用され、マイナーです。)SELECT
で参照されるすべての列が(PKの暗黙のコピーを含む)と同じセカンダリインデックスにある場合
を、そしてインデックスが」と言われていますカバーする "。したがって、クエリは、二次インデックスのBTree内で完全に実行され、それによって余分なステップが回避されます。繰り返しますが、これは通常小さいですが、行う価値があります。 「カバーリング」はEXPLAIN
に「インデックスの使用」(「インデックス条件の使用」ではなく、別のものを指す)で示されています。
私はIndexing Cookbookを学ぶことをお勧めします。私の文書はあなたにパフォーマンスのために重要なことを与え、この質問が議論しているような重要ではない詳細のいくつかを除外します。
小規模ののテーブルの場合、これらはいずれも重要ではありません。
巨大なテーブルでは、ディスクヒット数が主要なパフォーマンスメトリックです。それを最小化することが目標になります。特に、セカンダリインデックスのための余分なステップは、通常、N個のディスクヒット(N個の行)を必要とします。
しかし... SELECT ... GROUP BY ... ORDER BY ... LIMIT 1
は、一群の行を取り出し、並べ替え、最後に1行を配信することがあります。 インデックスでソートを使用できない場合は、N行が多分操作されます。 のケースでは、努力の99%が費やされた後にのみ、LIMIT 1
が動作します。これは、初心者のためのLIMIT
についてのよくある誤解です。
大丈夫です。ユニークキーと比較したプライマリキーは同じ測定可能な差異を持っていますか? – Alliswell
ありがとう、ゴードン! – Alliswell