嘿伙计们,尝试优化此查询以解决重复的用户问题:
SELECT userid, 'ismaster' AS name, 'false' AS propvalue FROM user
WHERE userid NOT IN (SELECT userid FROM userprop WHERE name = 'ismaster');
问题在于NOT IN之后的选择是120.000记录并且它将永远消失。
使用注释中建议的解释前缀返回:
QUERY PLAN
--------------------------------------------------------------------------------
--
Seq Scan on user (cost=5559.38..122738966.99 rows=61597 width=8)
Filter: (NOT (SubPlan 1))
SubPlan 1
-> Materialize (cost=5559.38..7248.33 rows=121395 width=8)
-> Seq Scan on userprop (cost=0.00..4962.99 rows=121395 width=8
)
Filter: ((name)::text = 'ismaster'::text)
(6 rows)
有什么建议吗?
答案 0 :(得分:0)
您是否在userid上添加了索引?
或尝试其他变体:
SELECT userid, 'ismaster' AS name, 'false' AS propvalue FROM user
WHERE NOT EXISTS
(SELECT * FROM userprop
WHERE userpop.userid = user.userid
AND name = 'ismaster');
答案 1 :(得分:0)
名称列是否已编入索引?名称值的选择性如何? 此外,只要您希望某人建议对查询进行更改,您就可以提供查询计划,即使是看似简单的查询也是如此。这样我们就知道规划师正在做什么。
答案 2 :(得分:0)
根据this answer,使用LEFT JOIN ... IS NULL
可能比NOT EXISTS
更快或更慢,具体取决于RDBMS,但它们在PostGres上是等效的。
SELECT u.userid, 'ismaster' AS name, 'false' AS propvalue FROM user u
LEFT JOIN userprop up ON u.userid = up.userid AND up.name <> 'ismaster'
WHERE up.userid IS NULL