若干ではあるが肯定形より否定形のWhere句の方が時間が掛かる。微々たるものなので、基本的には余分な回りくどい演算子は使わず『出来る限りレコード数を絞り込んでかつ素直に肯定形で書く』という考え方でよい。SQL文のWhere句に対する指定では、通常はある条件に”一致する”レコードだけを取り出すことが多いと思いますが、当然ある条件に”一致しない”レコードを取り出したい場合もあります。”一致する”と”一致しない”のどちらの指定によっても結果的に同じレコードが得られるなら、『Notや<>の否定形は使わない方がよい』という定石があります。テーブル上のインデックスを持ったあるフィールドに保存されている値が「1」もしくは「2」しかない場合、「1であるレコード」を抽出するのと「2でないレコード」を抽出するのとではどちらも同じ意味合いであり抽出されるレコードも基本的には同じになります。一般的には「NOTや<>の否定形ではインデックスは使われない」ということから、前者の方がよいということです。そこで今回は、このWhere句の違いによるパフォーマンスの違いをAccessにおいてチェックしてみたいと思います。ここでは、3種類のコードを用意して、その実行時間を比較してみます。ここで使う「tbl受注明細」テーブルは、「受注コード」が主キー、「商品コード」が重複ありのインデックスとなっており、100000件のレコードが保存されています。一つ目のプログラムでは、主キーである受注コードに対して一つだけWhere条件を指定します。結果的に取り出されるレコードは同じなのですが、一方は「受注コードが50000より大きい」という肯定形でWhere句を指定し、もう一方は「受注コードが50000以下でない」という否定形で指定しています。Sub二つ目のプログラムでは、主キーである受注コードとインデックスを持った商品コードの二つに対してANDで絞り込んだWhere条件を指定しています。一方は「受注コードが50000より大きくかつ商品コードが65800000である」という肯定形、もう一方は「受注コードが50000以下でなくかつ商品コードが65800000でなくはない(NOTと<>の併用)」という否定形で指定しています。Sub三つ目のプログラムでは3種類の方法を実行しています。「受注コードが50000である」、「受注コードが50000でなくはない」、「受注コードが”50000未満または50000より大きい”のではない」というように異なる表現をしていますが、実質的にはすべて「受注コードが50000である」レコードを抽出していることになります。50000」とずばり書くはずで、他の2つの方法を使うことはまずありませんが、ついでにテストしてみたいと思います。Sub上記3つの処理結果は次のようになりました(単位は秒)。肯定形4.660.970.89否定形4.681.000.91否定形232.84いずれも100000件のレコードのテーブルに対して100回のループ処理を繰り返している割にはわずかな時間差しかありませんが、あえて言えばですが、定石に近く「若干否定形の方が時間が掛かる」と言えるかもしれません(三つ目の結果の否定形2はもはや別格ですね、まずこういった書き方はする人はいないと思いますし...)。テストとしてかなり意図的にSQL文を組み立てている部分もあるので、結果としては「余分なあるいは回りくどい演算子は使わず、素直に書けばよい」ということも言えると思います。二つ目と三つ目は一つ目よりかなり短時間で処理が完了しています。これは「商品コード='65800000'」あるいは「受注コード=50000」というようにレコードを絞り込んでいるせいだと思われます。このことからも、当然どうしても否定形で書かざるを得ない場面は多々ありますが、もし結果が同じであれば『出来る限りレコード数を絞り込んでかつ素直に肯定形で書く』のが一番の得策と言えるのではないでしょうか?。50000だったら●●●する」といった書き方もできますが、そうではなく、レコードセットを開く時点のSQL(あるいはクエリ)の段階でできるだけレコードを絞り込んでおいた方がよいと言えます(これも常識的なことかもしれません)。