2

低レベルのキューとして設計されたテーブルの最初の N 行をフェッチする SQL クエリがあります。

select top N * from my_table where status = 0 order by date asc

このクエリの背後にある意図は次のとおりです。

  • まず、この質問はデータベースに依存しないことを意図しています。私の実装では、SQL Server、Oracle、DB2、および sybase がサポートされるためです。上記の "top N" の SQL 構文は単なる例です。
  • テーブルには数百万行を含めることができます。
  • N は比較的小さい数値で、たとえば 100 です。
  • 行がキューにある場合、status は 0 です。その後、処理中であることを示すために 1 に変更されます。処理後、削除します。そのため、テーブル内の行の少なくとも 90% がステータス 0 になることが予想されます。
  • テーブル内の行は、日付に従ってフェッチする必要があるため、order by句です。

このクエリを最速で動作させるための最適なインデックスは何ですか?

最初はインデックスが にあるはずだと思っていました(date, status)が、もうよくわかりません。ステータス列にはほとんどゼロが含まれるため、それに付加価値はありますか? 単独で索引付けするだけで十分(date)ですか?
それともそうあるべき(status, date)ですか?

4

2 に答える 2

2

RDMS に依存しない効率的なソリューションはないと思います。たとえば、Oracle にはビットマップ インデックスがあり、SQLServer には部分インデックスがあります。たとえば、Mysql や Sqlite に同様のものがない場合、それらを使用しない理由はわかりません。また、歴史的に、SQLServer は Oracle よりもクラスター化されたテーブル (または Oracle の世界では IOT) を実装しているため、日付列にクラスター化されたインデックスを使用すると、SQLServer では完全に機能しますが、Oracle では機能しません。

少しアプローチを変えたほうがいいです。行の 90% が条件を満たさないと言う場合はstatus=0、スキーマをリファクタリングして、関心のあるレコードのみを保持する新しいテーブル (またはマテリアライズド ビュー) を追加してみませんか? そのテーブルを最新の状態に保ち、データを元のテーブルとマージするために必要な新しいプログラム可能なオブジェクトの数は、RDMS がマテリアライズド ビューを直接サポートしていない場合でも、比較的少量です。また、基礎となるロジックを再設計して、行が更新されず、挿入または削除されるだけである場合、ロックの競合を回避するのに役立ち、その結果、システム全体のパフォーマンスが向上します。

于 2012-06-10T14:54:22.450 に答える
0

Date にクラスター化インデックスを設定し、Status に非クラスター化インデックスを設定します。

于 2012-06-10T15:04:28.290 に答える