• ベストアンサー

WHERE句の速度について

下記のSQLではどちらが高速でしょうか? 1) DELETE FROM t WHERE a = IN(1,2・・・10) 2) DELETE FROM t WHERE a=1 DELETE FROM t WHERE a=2 ・ ・ DELETE FROM a WHERE a=10

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

あるコンピュータメーカー系ソフトウェア会社に在籍し、DBMSの設計部署に長年在籍していました。 以下の例で説明します。 (1)DELETE FROM 表名 WHERE 列名 IN(値1,値2,値3) (2)DELETE FROM 表名 WHERE 列名=値1 OR 列名=値2 OR 列名=値3 (3)DELETE FROM 表名 WHERE 列名=値1 DELETE FROM 表名 WHERE 列名=値2 DELETE FROM 表名 WHERE 列名=値3 (3)は構文解析だけでなく、何度もサーバとのやり取りが発生するので、オーバヘッドが多くなります。 (2)はORでつなげた条件が、INと等価であることがDBMSで判断できるか否かで、処理時間がINと同等になるか劣るかになります。 実際にそこまでDBMSで判断できないケースは、少なくありません。 (1)IN条件であることが明らかなので、DBMSから見ればオーバヘッドは少ないです。 ただし、他の方も書いていますが、範囲条件にできるものをIN条件にしているなら、範囲条件にした方が早いです。

php4
質問者

お礼

2)について。Explainを使う意味がすごく理解できました。先生ありがとうございます♪ DBエンジニアも良いお仕事ですね。 今回は、範囲条件にはできませんが、もっと早くする方法を追求する意識が持てるようになりたいと思いました。

その他の回答 (4)

回答No.5

DBサーバがSQLを発行するプログラムと別のマシンかどうかや、RDBMSが何かなどと関係してくるため、この情報だけでははっきりとした解答は得られないと思います。 私の予想ではRDBMS内の計算よりRDBMSへのSQLの発行のほうがコストが高いと思われますので、1の方が高速だと思います。 RDBMSがMySQLやPostgreSQLの場合、EXPLAINを使うことによってWHRER区の効率を調べることができますので活用されてはいかがでしょうか。

php4
質問者

お礼

プログラムとサーバーは別になります。 結局、INを使う事にしました。 ありがとうございます。

  • inu2
  • ベストアンサー率33% (1229/3720)
回答No.3

WHERE a >= 1 AND a<=10; のほうが手っ取り早いかと・・・ aに 1.20や2.15 などの小数点も含まれていてそれらを消したくない場合はまた別ですけどね もしくは、 WHERE a=1 OR a=2 OR ・・・OR a=10; とかね どんな機能を実装させようとしてDELETEしてるのかわかりませんが、私の場合は、デリートフラグ のカラム(フィールド)を作っておいて DELETEさせたい場合はDELETEを使わずに UPDATE で たとえば、SET del_flg = 1 WHERE a=1; 等にさせておきますね 万が一消してはだめだった レコードだった場合、簡単に復旧できますしね。 管理のためのメンテナンス時と、web上で操作につかう ユーザー名、パスワード を別々にさしておきます 管理者の操作用のユーザー名パスワードにはDELETE権限を持たせる web上で不特定多数が操作するとき用のユーザー名パスワードは INSERT、UPDATE 、SELECT のみを許可する もっと細分化してもかまわないとおもいます。 別に設定しておくことで 万が一インジェクションされたときに、まっさらに消されてしまうのを防ぐのと、DELETEって結構ぐちゃぐちゃしてゴミ残ります(表向きではなく、データベースサーバーの中でです

php4
質問者

お礼

del_flgについては、もっと頑張って考えてみようと思います。ありがとうございます。 全てのテーブルをDEL_FLGありにすれば web上で不特定多数が使うユーザーをDELETE権限なしにする設定は、レコード数がそれほど増えないシステムな場合シンプルで良さそうですね。 MySQLではテーブル単位のアクセス権は設定できないですし。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

構造上は1が速いだろうと予測できるのは#1さんに 同意ですが1をするためにはプログラムでINないの データを作ることになりますよね? 制約上INは無限にデータをつなげることはできません。 それをプログラムで解析しながら冗長にかくと かえってオーバーヘッドがおおきいかもしれません。 おそらく人が認識できるほどの速度の差は出ないと おもいますので、どちらでよい・・・というのが 妥当な回答になります。

php4
質問者

お礼

INは無限ではなかったのですね。知りませんでした(汗) 今回は10レコードの削除ということで大丈夫ですが気をつけます。ありがとうございます。

  • NNori
  • ベストアンサー率22% (377/1669)
回答No.1

1)でしょう。だって構文解析が1回しか動かないもん。 ちなみに = はいらないのでは?

php4
質問者

お礼

構文解析は、プログラム側でprepareというコマンドを実行すれば1度で済みますが今回はprepareを実行しないので1)にします。INはご指摘の通り=いらなかったです。ありがとうございました。

関連するQ&A