web-dev-qa-db-ja.com

Postgresの主キーは逆の順序でソートされています。インデックスを効率的に使用しますか?

私のRailsデータベースはPostgresデータベースによってサポートされています。ご存知のとおり、Railsの各テーブルには、整数型でインデックスが付けられた主キーが割り当てられます。

リストビューでは、レコードが新しい順に表示されます。そのため、主キーの逆の順序で結果セットを並べ替えるだけです。

私の質問は:クエリは主キーインデックスを使用しますか?そして、もしそうなら、効率的に?どうすれば確認できますか?

よろしくお願いします。

バーラト

7
Bharat

インデックスは通常、単方向です。これにより、バックリンクを維持する必要がないため、スペースとインデックスのスキャン速度が向上します。 @a_horse_with_no_nameが指摘したように、Postgresはインデックスと逆の順序で検索するために使用できます。 (これがNULLのない一意のインデックスではなかった場合、NULLS FIRST/LASTの配置が考慮される可能性があります。)パフォーマンスは非標準のインデックスの順序を使用する場合ほど速くない可能性があります。 -標準の注文。

インデックスの逆スキャンをサポートしていないシステムでは、インデックスが昇順の場合、インデックスはクエリに使用されません。この場合、2つのオプションがあります。

  • DESCを指定して別のインデックスを追加します。または
  • 主キーインデックスを、DESCが指定されているインデックスで置き換えます。 (私はこれを試したことがなく、主キーに対する私の期待に反するため、おそらくそうしないでしょう。)
3
BillThor

Postgresのドキュメントから: 第11章インデックス8.3章11.インデックス のような本当に古いバージョンでも同じことが言えます):

デフォルトでは、Bツリーインデックスはエントリを昇順で格納し、最後にnullを付けます。これは、列xのインデックスのフォワードスキャンにより、ORDER BY x(またはより詳細にはORDER BY x ASC NULLS LAST)を満たす出力が生成されることを意味します。 インデックスを逆方向にスキャンしてORDER BY x DESCを満たす出力を生成することもできます(または、ORDER BY x DESC NULLS FIRSTNULLS FIRSTのデフォルトであるため、ORDER BY DESCより冗長になります)。


このインデックスが特定のステートメントで使用されるかどうかは、実際にはステートメントに依存します。テーブル全体またはテーブルの大部分を返すクエリの場合:

SELECT *
FROM tablex
ORDER BY tablexID DESC ;

とにかくテーブル全体をスキャンする必要があるため、オプティマイザはテーブル全体を読み取ってから降順でソートする方が安くなると判断する場合があります(このインデックスを使用しないでください)。

ただし、次のようなクエリの場合は、インデックスのみを使用すると思います(インデックスに格納されているID以外のデータは必要ないため)。

SELECT tablexID
FROM tablex
WHERE tablexID <= 5000
ORDER BY tablexID DESC ;

したがって、インデックスが使用されるかどうかは、実行しているステートメント、キャッシュ設定、結合のタイプ、使用している条件、使用可能な/相対的なすべてのインデックス、テーブルの統計、およびインデックス(サイズ、分布、カーディナリティなど)、Postgresのバージョン(異なるバージョンは異なる最適化を意味します)、月の位相、そしておそらく私が忘れている他の多くの要素。


特定の時点で特定のステートメントに使用されるインデックスがある場合は、それを確認するために、 EXPLAIN を使用してその実行プランを確認できます。

6
ypercubeᵀᴹ