0

ユーザー インターフェイスにデータを返すために order by を使用しているシステムがあります。ユーザーは、さまざまな並べ替えオプションから任意の順序で選択できます。

クエリがあります

explain extended select t.* from task t order by create_date, due_date limit 5;

+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra          |
+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+
|    1 | SIMPLE      | t     | ALL  | NULL          | NULL | NULL    | NULL | 331233 |   100.00 | Using filesort |
+------+-------------+-------+------+---------------+------+---------+------+--------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

create_date と due_date にインデックスがあります。複数列のインデックスを作成できることはわかっています。ただし、約 12 の異なる並べ替えオプションがあるため、すべてのシナリオをカバーするには 100 を超えるインデックスを作成する必要があります。

インデックスのマージについて読みましたが、並べ替えることができる各列のインデックスを作成できるため、問題は解決すると思いますが、クエリの「順序付け」部分では機能しないようです。

4

3 に答える 3

1

DBMS は、インデックスがない場合でもソートに優れています。余分なインデックスは更新操作を遅くすることに注意してください。そのため、テーブルの「インデックスが多すぎる」などの事態が確実に発生する可能性があります。

クエリが複雑な場合にインデックスを使用してデータを表示できるという保証や、インデックスを使用することが最速のクエリ プランであるという保証はありません。

たとえば、ColumnB と ColumnC で並べ替えたいときに、ColumnA で非常に適切なフィルター条件 (テーブル内の 100 万行の 1/1000 だけを選択する) を使用する場合があります。その場合、オプティマイザーは、ColumnB と ColumnC のインデックスの順序で 1,000,000 行のテーブル全体を読み取り、1000 行から 1 つを選択するよりも、ColumnA のインデックスを使用して 1000 行の結果行を並べ替える方がパフォーマンスが向上する可能性があります。フィルター条件。

通常、オプティマイザーはユーザーよりもよく知っています。常にではない; 実装には時折バグや見落としさえあります。しかし、最初の経験則として、クエリを書き直して同じ結果を大幅に高速化できない限り、オプティマイザーはまともな仕事をしている可能性があります。(クエリを書き直して結果をより速く得ることができれば、オプティマイザーはそれを吹き飛ばし、バグレポートの良い基礎を手に入れました。)

于 2013-01-12T05:28:45.830 に答える
0

あなたができる唯一の方法は、インデックスを強制することです

order by のインデックス index_name を強制する

インデックス マージを利用したい場合は、union や などを使用してみてください。これにより、マルチ インデックスを使用できるようになります。

マルチインデックスは、互いに独立した両方の条件が機能するときに使用されることを常に覚えておいてください。

まれに、マルチインデックスを利用できる場合があります

(ここで上記のクエリについては、うまくいかないと確信しています)

于 2013-01-12T06:39:58.963 に答える
0

この回避策を試してください:

explain extended select * from (select t.* from task t order by create_date limit 30) z order by create_date, due_date limit 5;

最初の順序を使用しているときに、すべての行が上位 30 行以内にある場合に機能します。

「トリック」は、メインテーブルから単純なクエリを選択し、330K 行のテーブル全体を使用するよりも高速に、30 行のセットでより大きな処理 (結合、高度な注文、ランダムなど) を実行することです。

于 2013-02-07T11:02:22.517 に答える