2つのテーブルがあります。ここでは詳細は重要ではない1つの変更ログテーブル。販売者情報を保持し、最も重要な2つの列を持つ別のテーブル:
- プライマリID
- ident(=実世界ID)と呼ばれるID。
売り手が変更されると、新しいエントリが作成され、IDは同じままですが、新しいエントリは新しいIDになります。IDにプライマリインデックスがあり、(ident、-id)に別のインデックスがあるので、現在のデータをすばやく取得できます。
偶然にも、私は次の奇妙な行動を見つけました:
これは、完了するのに非常に長い時間がかかります。
SELECT DISTINCT ON (ident) sellers.* FROM changelog, sellers ORDER BY ident,id DESC;
QUERY PLAN
---------------------------------------------------------------------------------
Unique (cost=741675.98..760122.47 rows=10 width=30)
-> Sort (cost=741675.98..750899.22 rows=3689298 width=30)
Sort Key: sellers.ident, sellers.id
-> Nested Loop (cost=3.07..74457.37 rows=3689298 width=30)
-> Seq Scan on changelog (cost=0.00..668.34 rows=38034 width=0)
-> Materialize (cost=3.07..4.04 rows=97 width=30)
-> Seq Scan on sellers (cost=0.00..2.97 rows=97 width=30)
DESCを-IDに置き換えると高速ですが、同じ結果が得られます。
SELECT DISTINCT ON (ident) sellers.* FROM changelog, sellers ORDER BY ident,-id;
QUERY PLAN
------------------------------------------------------------------------------------------
Unique (cost=706.37..92956.53 rows=10 width=30)
-> Nested Loop (cost=706.37..83733.28 rows=3689298 width=30)
-> Index Scan using idx_sellers on sellers (cost=0.00..17.70 rows=97 width=30)
-> Materialize (cost=706.37..1086.71 rows=38034 width=0)
-> Seq Scan on changelog (cost=0.00..668.34 rows=38034 width=0)
FROMから「changelog」を削除すると、ORDERBY-idとDESCは同じクエリプランをすばやく実行します。
SELECT DISTINCT ON (ident) sellers.* FROM sellers ORDER BY ident,id, DESC
QUERY PLAN
---------------------------------------------------------------------
Unique (cost=6.17..6.66 rows=10 width=30)
-> Sort (cost=6.17..6.41 rows=97 width=30)
Sort Key: ident, id
-> Seq Scan on sellers (cost=0.00..2.97 rows=97 width=30)
私の質問:
- FROMに未使用のテーブルを含めるとクエリにまったく影響するのはなぜですか?
- ORDER BY ident、-idがORDER BY ident、id DESCと同じプランを使用しないのはなぜですか?
編集:私の実際のクエリには、もちろん2つのテーブルを結合するためのWHERE句があります。