【发布时间】:2013-07-22 17:13:37
【问题描述】:
任何想法如何加快这个查询?
输入
EXPLAIN SELECT entityid FROM entity e
LEFT JOIN level1entity l1 ON l1.level1id = e.level1_level1id
LEFT JOIN level2entity l2 ON l2.level2id = l1.level2_level2id
WHERE
l2.userid = 'a987c246-65e5-48f6-9d2d-a7bcb6284c8f'
AND
(entityid NOT IN
(1377776,1377792,1377793,1377794,1377795,1377796... 50000 ids)
)
输出
Nested Loop (cost=0.00..1452373.79 rows=3865 width=8)
-> Nested Loop (cost=0.00..8.58 rows=1 width=8)
Join Filter: (l1.level2_level2id = l2.level2id)
-> Seq Scan on level2entity l2 (cost=0.00..3.17 rows=1 width=8)
Filter: ((userid)::text = 'a987c246-65e5-48f6-9d2d-a7bcb6284c8f'::text)
-> Seq Scan on level1entity l1 (cost=0.00..4.07 rows=107 width=16)
-> Index Scan using fk_fk18edb1cfb2a41235_idx on entity e (cost=0.00..1452086.09 rows=22329 width=16)
Index Cond: (level1_level1id = l1.level1id)
好吧,这里是简化版,连接不是瓶颈
SELECT enitityid FROM
(SELECT enitityid FROM enitity e LIMIT 5000) a
WHERE
(enitityid NOT IN
(1377776,1377792,1377793,1377794,1377795, ... 50000 ids)
)
问题是要找到没有这些 id 的实体
解释
Subquery Scan on a (cost=0.00..312667.76 rows=1 width=8)
Filter: (e.entityid <> ALL ('{1377776,1377792,1377793,1377794, ... 50000 ids}'::bigint[]))
-> Limit (cost=0.00..111.51 rows=5000 width=8)
-> Seq Scan on entity e (cost=0.00..29015.26 rows=1301026 width=8)
【问题讨论】:
-
您需要向我们展示表和索引定义。 诊断慢查询需要完整的表和索引定义,而不仅仅是描述或解释。也许您的表格定义不佳。也许索引没有正确创建。也许您认为您在该列上没有索引。没有看到表和索引定义,我们无法判断。如果您知道如何进行
EXPLAIN或获得执行计划,请将结果也放入问题中。 -
很可能是那个 NOT IN 子句中的 50,000 个 ID 会强制进行完整的顺序扫描。但是我们必须看到表定义才能知道。
-
是否有关于实体(实体id)的索引?是PK吗?你
analyze桌子了吗? -
是的,它的主键
标签: performance postgresql postgresql-performance