レコードに一意な値が2つある場合、SELECT文のWHEREで AND 指定した方が良い?

投稿者: Anonymous

レコードに一意な値が入るカラムが2つあります
・id
・url

この時、下記SQL文の取得結果速度に違いはあると考えられますか?

SQL1.SELECT * FROM テーブル名 WHERE id = 1;

SQL2.SELECT * FROM テーブル名 WHERE id = 1 AND url ='https://ja.stackoverflow.com/';
  • どちらも同じ
  • SQL1.の方が速い
  • SQL2.の方が速い
  • 環境(メモリやデータ内容)による

追記
回答を読んで知りたいと思った内容を改めて整理してみました。

レコード例(下記のような一意の組み合わせがあります)

1 スタック・オーバーフロー 'https://ja.stackoverflow.com/'
2 Google 'https://www.yahoo.co.jp/'
3 Yahoo! JAPAN 'https://www.google.com/'

Q1(AUTOINCREMENET属性も、インデックスも、設定していない時)
・1レコード目を取得したい場合、1だけを指定するSELECTと、1と’https://ja.stackoverflow.com/‘を指定するSELECTに違いはありますか?

Q2(AUTOINCREMENET属性だけを設定している時)
・1レコード目を取得したい場合、1だけを指定するSELECTと、1と’https://ja.stackoverflow.com/‘を指定するSELECTに違いはありますか?

Q3(複合インデックスを設定している時)
・1レコード目を取得したい場合、1だけを指定するSELECTと、1と’https://ja.stackoverflow.com/‘を指定するSELECTに違いはありますか?

解決

こんにちは。同じ環境であれば、このケースではSQL1.が速くなると思われます。

複合インデックスがはられてない場合は言うまでもありませんので、複合インデックスがはられていることを前提に話を進めます。

idは(おそらくは)固定長の数値一個のインデックスとなるからです。複合インデックスがはられている場合は、インデックスをはられているコラムの内容により検索性能に差が出ます。
urlは文字列であり、固定長の文字列の場合も配列となるので、数値一個の時より性能は落ちます。またこれが可変長の文字列だった場合さらに状況は悪くなるでしょう。

(SQL Serverの話題になりますが)類似の質問と回答が本家にありましたのでPerformanceDBA氏の回答を一部参考にしています。
https://stackoverflow.com/questions/4011600/sql-server-performance-difference-with-single-or-multi-column-primary-key

[追記への回答]
AUTOINCREMENTだけ指定しているという状況がわかりませんが、これはつまり、PKEYになっているという想定で話を進めます。PKEYの場合は暗黙的にインデックスが貼られてUNIQUEになっています。(実運用上は文字列フィールドにもUNIQUEをつけてくださいね)

Q1. この場合ともにフルスキャンがかかりますが、比較にかかるコストが数値の方が低いためIDを指定して検索したほうが早くなります。ただし主キーがないテーブルは作らないでください。
Q2. PKEYがIDに設定されているものとして話をすすめます。この場合もIDを検索した方がはやくなります。二つ目の条件では文字列フィールドに対してフルスキャンがかかるためかなり遅くなります。
Q3. これは先に挙げた回答のとおりです。この場合IDへのインデックスと、複合インデックスの速度の比較になりますが、インデックスの性能差から、やはりID指定の検索が早くなります。

MySQLのお話だと思いますのでインデックスについては下記を参照にしてください
https://dev.mysql.com/doc/refman/5.6/ja/optimization-indexes.html

インデックスとフルスキャンの違いについて補足すると
フルスキャンの概念としては文字通り、辞書を1ページ目から調べて対象が見つかるまで調べ続ける状態となります。(UNIQUEがないと頭から終わりまで調べます)。インデックスがある場合は用語集を見てそのページに直接移動して調べる感じです。より深い理解のためには上述の章を確認してBツリーや、ハッシュなどについて学習を行うことをお勧めします。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *