【发布时间】:2012-11-17 14:29:42
【问题描述】:
我在 Postgres 9.1 数据库上运行了两个不同的 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 秒运行(3620 个子句用 OR 分隔)
和
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 秒运行(3620 子句用 OR 分隔)
在第一个中,国家/地区条件在每个子句中都是相同的。在第二个中,我在最后一个子句中将国家/地区切换为“不同”。
第一个 select 语句需要 12 秒运行,第二个 select 语句需要 0.6 秒运行。
在第一个查询中,CPU 在几乎所有 12 秒内都固定在 100%,而没有任何磁盘读取,这表明它很可能是解析器花费了这么长时间。第二个查询不会发生这种情况。
我已经运行了 EXPLAIN ANALYZE 并获得了完全相同的结果来了解两个查询的分解方式。
这里发生了什么?为什么每个 WHERE 子句语句中的第二个条件相同会导致查询时间更长?
编辑:
EXPLAIN ANALYZE 来自第一个查询的前几行:
设备上的位图堆扫描(成本=18807.49..52584.74 行=3564 宽度=39)(实际时间=73.994..78.994 行=3620 循环=1)
重新检查条件:(((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))
第二个查询中 EXPLAIN ANALYZE 的前几行:
设备上的位图堆扫描(成本=18806.59..85317.68 行=3563 宽度=39)(实际时间=74.737..79.769 行=3619 循环=1)
重新检查条件:(((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:
以下是两个 EXPLAIN ANALYZE 结果:
【问题讨论】:
-
很高兴在这里看到您的
EXPLAIN ANALYZE输出。哪个 PostgreSQL 版本?.. -
PostgreSQL9.1.我刚刚添加了 EXPLAIN ANALYZE 的结果
-
请将执行计划上传到explain.depesz.com 或至少正确格式化(使用
<pre>标签)以便保留缩进。 -
前几行还不够,需要完整输出。
-
解释分析表明两个查询花费的时间大致相同,不到 80 毫秒。你在哪里测量 12 秒?
标签: postgresql select