Postgres9.1データベースで実行している2つの異なるSQLクエリがあります。
SELECT device_id, country FROM devices WHERE
(device_id = '97c179bd' AND country = 'US') OR
(device_id = 'bf5f50c6' AND country = 'US') OR
....
(device_id = '0e66c04d' AND country = 'US')
実行に12秒(ORで区切られた3620句)
と
SELECT device_id, country FROM devices WHERE
(device_id = '97c179bd' AND country = 'US') OR
(device_id = 'bf5f50c6' AND country = 'US') OR
....
(device_id = '0e66c04d' AND country = 'US') OR
(device_id = '0e66c04d' AND country = 'different')
実行に0.6秒(ORで区切られた3620句)
最初のものでは、国の条件はすべての条項で同じです。2つ目では、最後の句で国を「異なる」に切り替えました。
最初のselectステートメントの実行には12秒かかり、2番目のselectステートメントの実行には0.6秒かかります。
最初のクエリでは、ディスクの読み取りが行われずに、CPUが12秒間のほぼすべてで100%に固定されています。これは、非常に時間がかかるパーサーである可能性が高いことを示しています。これは、2番目のクエリでは発生しません。
EXPLAIN ANALYZEを実行したところ、両方のクエリがどのように分類されたかについて、まったく同じ結果が得られました。
ここで何が起こっているのですか?各WHERE句ステートメントで2番目の条件が同じであると、クエリ時間が大幅に長くなるのはなぜですか。
編集:
最初のクエリからのEXPLAINANALYZEの最初の数行:
デバイスでのビットマップヒープスキャン(コスト=18807.49..52584.74行=3564幅=39)(実際の時間=73.994..78.994行=3620ループ=1)
Condを再確認します:(((device_id = '97c179bd' :: text)AND(country ='US' :: text))OR((device_id ='bf5f50c6' :: text)AND(country ='US' :: text) )OR((device_id = '3b05d35a' :: text)AND(country ='US' :: text))OR((device_id ='c6684bc0' :: text)AND(country ='US' :: text))OR ((device_id = '0e66c04d' :: text)AND(country ='US' :: text))
2番目のクエリからのEXPLAINANALYZEの最初の数行:
デバイスでのビットマップヒープスキャン(コスト=18806.59..85317.68行=3563幅=39)(実際の時間=74.737..79.769行=3619ループ=1)
Condを再確認します:(((device_id = '97c179bd' :: text)AND(country ='US' :: text))OR((device_id ='bf5f50c6' :: text)AND(country ='US' :: text) )OR((device_id = '3b05d35a' :: text)AND(country ='US' :: text))OR((device_id ='c6684bc0' :: text)AND(country ='US' :: text))OR ((device_id = '0e66c04d' :: text)AND(country ='US' :: text))
編集2:
EXPLAINANALYZEの2つの結果は次のとおりです。