【发布时间】:2020-11-15 06:32:14
【问题描述】:
我正在尝试对 id 进行查询优化。不确定我应该使用哪一种方式。下面是使用explain 的查询计划,成本方面看起来很相似。
1. explain (analyze, buffers) SELECT * FROM table1 WHERE id = ANY (ARRAY['00e289b0-1ac8-451f-957f-e00bc289148e'::uuid,...]);
QUERY PLAN:
Index Scan using table1_pkey on table1 (cost=0.42..641.44 rows=76 width=835) (actual time=0.258..2.603 rows=76 loops=1)
Index Cond: (id = ANY ('{00e289b0-1ac8-451f-957f-e00bc289148e,...}'::uuid[]))
Buffers: shared hit=231 read=73
Planning Time: 0.487 ms
Execution Time: 2.715 ms)
2. explain (analyze, buffers) SELECT * FROM table1 WHERE id = ANY (VALUES ('00e289b0-1ac8-451f-957f-e00bc289148e'::uuid),...);
QUERY PLAN:
Nested Loop (cost=1.56..644.10 rows=76 width=835) (actual time=0.058..0.297 rows=76 loops=1)
Buffers: shared hit=304
-> HashAggregate (cost=1.14..1.90 rows=76 width=16) (actual time=0.049..0.060 rows=76 loops=1)
Group Key: "*VALUES*".column1
-> Values Scan on "*VALUES*" (cost=0.00..0.95 rows=76 width=16) (actual time=0.006..0.022 rows=76 loops=1)
-> Index Scan using table1_pkey on table1 (cost=0.42..8.44 rows=1 width=835) (actual time=0.002..0.003 rows=1 loops=76)
Index Cond: (id = "*VALUES*".column1)
Buffers: shared hit=304
Planning Time: 0.437 ms
Execution Time: 0.389 ms
看起来VALUES () 做了一些散列和连接以提高性能,但不确定。
注意:在我的实际用例中,id 是 uuid_generate_v4() e.x。 d31cddc0-1771-4de8-ad41-e6c568b39a5d 但该列可能不会被索引。
另外,我有一张5-10 million records 的表格。
哪种方式查询性能更好?
【问题讨论】:
-
您的示例中的数据量太小,以至于查询计划中的这种差异并不重要。除非您的数据更大,否则没有理由担心。看起来
VALUES()的使用需要一个额外的步骤来删除重复项。这对您的实际查询可能有用也可能没用。 -
我有一个包含 5-10 百万条记录的表。在问题中添加了此信息。
-
请使用这两个查询对该表运行
explain (analyze, buffers),然后edit您的问题并添加这些执行计划。 -
用实际查询结果更新了问题。
-
我不明白您所说的“可能不是这样的索引”是什么意思。您的计划清楚地表明您有一个包含
id列的索引。两个计划之间的性能差异仅是由于第一个计划必须从磁盘中读取一些块 (read=73) 造成的,而在第二个计划中,所有内容都在缓冲区缓存中。如果您多次运行第一个,您可能会得到与第二个相同的执行时间。在任一情况下,两者都处理相同数量的块(304)。如果所有内容都被缓存,我实际上希望第一个计划更快。
标签: sql postgresql query-optimization where-clause