4

ORDER BYandLIMIT句を含むかなり複雑なクエリがあります。が主キーを使用する場合ORDER BY、クエリにかかる時間は 5 ミリ秒未満です。ORDER BYただし、別の列 (タイプ ) によって実行されるようにクエリを変更するFLOATと、応答時間は 50 秒を超えます (4 桁も高くなります!)。

さて、問題は、主キーで並べ替えられたクエリがインデックス スキャンを実行するのに対し、float 列で並べ替えられたクエリは順次スキャンを実行し、最後に並べ替えが必要になることだと思います。

float 列にインデックスを追加するだけで、Postgresql がこのクエリをよりスマートな方法で計画するのに十分だと思いました。どうやら私が間違っていたようです。何を見逃したのでしょうか?

編集:EXPLAIN ANALYZE質問を投稿する前に実行しました。したがって、私の推測は単なる推測ではありません。ただし、 の出力はEXPLAIN ANALYZE30 行を超えて実行されるため、1 つのクエリがインデックスを使用し、もう 1 つのクエリがすべての行を並べ替えなければならない理由はすぐにはわかりません。

4

3 に答える 3

4
  1. クエリに対してexplainanalyzeを実行します。これにより、何が起こるかを推測する必要がなくなります。
  2. クエリを最適化するには、通常、Explain Analysisの出力とクエリを読んでから、最善のアクションを見つける必要があります。場合によっては、インデックスを追加することもあれば、クエリを書き換えることもあります。ただし、説明もクエリも表示されないため、どちらがケースに最適かを判断することはできません。
于 2013-02-06T17:13:07.097 に答える
2

クエリを見ずに何が起こっているのかを解読するのは非常に困難です。私の推測では、クエリプランは、データを適切な順序に保ちながら、主キーを持つテーブルに基づいて結合を実行できると思います。次に、クエリプランは基本的に行をフェッチし、他のテーブルで値を検索し、それらをマッサージして、値を順番に返します。処理は可能な限り行われlimitます。

これをの別の列に置き換える場合はorder byすべての行を処理する必要があります。これらはソートされて返されます。基になるテーブルのサイズである場合もあれば、結果セットのサイズである可能性があり、結果として処理が長くなります。ただし、基本的な理由は、すべての行を生成する必要があることです。

于 2013-02-06T17:13:35.490 に答える
0

多くの行を返すクエリの場合、データベースが非カバー インデックスを使用することはまれです。テーブル ルックアップ (インデックスからテーブル データまで) のコストが高すぎます。代わりにテーブル スキャンが使用されます。

例えば、

select name from people where name > 'N' order by birthdate

データベースは のインデックスを使用します(birthday)か? プラス面として、行は正しい順序で返されます。欠点としては、すべての行で列のテーブル ルックアップが必要になりnameます。2 番目ははるかにコストがかかるため、インデックスは使用されません。

のインデックス(birthday, name)が異なります。名前が含まれているため、テーブルのルックアップは必要ありません。データベースはインデックスを使用して、行を正しい順序ですばやく返すことができます。

クエリに必要なすべての列を含むインデックスは、カバリング インデックスと呼ばれます。クエリで使用されるすべての列がインデックスに含まれていることを確認してから、もう一度やり直してください。

于 2013-02-06T17:10:57.817 に答える