数億行のデータベースがあります。私は次のクエリを実行しています:
select * from "Payments" as p
inner join "PaymentOrders" as po
on po."Id" = p."PaymentOrderId"
inner join "Users" as u
On u."Id" = po."UserId"
INNER JOIN "Roles" as r
on u."RoleId" = r."Id"
Where r."Name" = 'Moses'
LIMIT 1000
where句がデータベースで一致するものを見つけると、数ミリ秒で結果が得られますが、クエリを変更しr."Name"
てwhere句に存在しないものを指定すると、完了するまでに時間がかかりすぎます。Payments
PostgreSQLは、各行を1つずつ比較して、テーブル(最も多くの行を含む)に対して順次スキャンを実行していると思います。
Roles
postgresqlは、テーブルに次の行が含まれているかどうかを最初にチェックするのに十分スマートではありませんName
'Moses'
か?
Rolesテーブルには15行しか含まれていませんが、Paymentsには約3億5000万行が含まれています。
PostgreSQL9.2.1を実行しています。
ところで、同じスキーマ/データに対するこの同じクエリは、MSSQLServerで完了するのに0.024msかかります。
質問を更新し、数時間以内にEXPLAINANALYZEデータを投稿します。
分析結果の説明:http://explain.depesz.com/s/7e7
そして、ここにサーバー構成があります:
version PostgreSQL 9.2.1, compiled by Visual C++ build 1600, 64-bit
client_encoding UNICODE
effective_cache_size 4500MB
fsync on
lc_collate English_United States.1252
lc_ctype English_United States.1252
listen_addresses *
log_destination stderr
log_line_prefix %t
logging_collector on
max_connections 100
max_stack_depth 2MB
port 5432
search_path dbo, "$user", public
server_encoding UTF8
shared_buffers 1500MB
TimeZone Asia/Tbilisi
wal_buffers 16MB
work_mem 10MB
私はpostgresqlをi5cpu(4コア、3.3 GHz)、8 GBのRAM、およびCrucial m4SSD128GBで実行しています。
更新 これはクエリプランナーのバグのようです。Erwin Brandstetterの推薦で、私はそれをPostgresqlバグメーリングリストに報告しました。