我有一个简单的查询(postgresql,如果重要的话),检索some_user的所有项目,不包括她在心愿单上的项目:
select i.*
from core_item i
left outer join core_item_in_basket b on (i.id=b.item_id and b.user_id=__some_user__)
where b.on_wishlist is null;
以上查询运行在~50000ms(是的,数字是正确的)。 如果我删除“b.on_wishlist为null”条件或使其“b.on_wishlist is not null”,则查询将在大约50ms内运行(相当大的变化)。
查询有更多的连接和条件,但这是无关紧要的,因为只有这个减慢了它。
有关数据库大小的一些信息:
我在这两个表上没有任何索引(除了id和外键)。
问题是:我应该怎么做才能让这个更快跑?我今晚有一些想法可以查看,但我希望你们能帮助我们,同样。
谢谢!
答案 0 :(得分:5)
尝试使用not exists:
select i.*
from core_item i
where not exists (select * from core_item_in_basket b where i.id=b.item_id and b.user_id=__some_user__)
答案 1 :(得分:2)
您可能想要详细解释此查询的目的 - 正如某些技术所做的那样,有些技术没有意义,具体取决于用例。
你多久运行一次?
它是仅为1个用户运行,还是在某种循环中为所有用户运行?
执行:解释分析并将输出放在explain.depesz.com上,这样你就会明白它为什么这么慢。
答案 2 :(得分:2)
很抱歉添加第二个答案,但stackoverflow不允许我正确格式化评论,因为格式化是必不可少的,我必须发布答案。
几个选项:
让我们知道结果:)
答案 3 :(得分:1)
您是否尝试在on_wishlist
上添加索引?
似乎需要为查询中的每一行检查此列。如果您的表很大,这可能会对查询速度产生非常大的影响。
当您在on_wishlist
子句中放置where
条件时,这将导致它(取决于查询器所决定的内容)在执行连接后进行评估,该比较必须可以为连接产生的每一行完成。 core_items
和core_item_in_basket
表都非常大,并且您没有该列的索引,因此查询优化器几乎没有,这可能会导致查询时间过长
core_user
的大小应该没有影响(因为它没有在查询中引用)。