如何优化此mysql语句?
SELECT DISTINCT p.name
FROM Something_Meta s1
JOIN Something_Meta s2 ON s1.fk_somethingId = s2.fk_somethingId
JOIN Products p ON s2.fk_productId = p.id
JOIN
(
select fk_id from Restricted where fk_foo != 233 and fk_id NOT IN
(
Select fk_id from Restricted where fk_foo = 233
)
)
r ON r.fk_id = p.id
WHERE s1.fk_somethingId = 63 AND s2.fk_somethingId <> s1.fk_somethingId
order by p.name ASC
我的桌子就像那样
Product (id,name )
Restricted (id,fk_id,fk_foo )
Something_Meta (id,fk_id,fk_somethingId )
fk_id是产品的外键(id)
可能是sql语句需要优化..
select fk_id from Restricted where fk_foo != 233 and fk_id NOT IN
(
Select fk_id from Restricted where fk_foo = 233
)
整个查询语句的运行时间超过1.5秒,单个查询的网站需要多秒。
答案 0 :(得分:0)
您可以尝试(fk_foo, fk_id)
上的索引来覆盖整个查询:
create index ix_restricted_fk_foo_fk_id(fk_foo, fk_id) on restricted
答案 1 :(得分:0)
首先关闭:DISTINCT
有点红旗。如果您需要过滤掉双打,那么可能会出现错误(在查询或设计中)导致双打。
二;你可以写这样的查询:
SELECT DISTINCT p.name
FROM Something_Meta s1
JOIN Something_Meta s2 ON s1.fk_somethingId = s2.fk_somethingId
JOIN Products p ON s2.fk_productId = p.id
WHERE s1.fk_somethingId = 63 AND s2.fk_somethingId <> s1.fk_somethingId
AND NOT EXISTS ( SELECT *
FROM Restricted r
WHERE r.fk_foo != 233
AND r.fk_id = p.id )
AND EXISTS ( SELECT *
FROM Restricted r2
WHERE r2.fk_foo = 233
AND r2.fk_id = p.id )
order by p.name ASC
由于我对Something_Meta
表没有任何线索,我只关注Restricted
表并建议你在fk_foo和fk_id上放一个索引。所述索引不是查询的一部分,而是表的一部分,因此您必须预先定义一次。
CREATE INDEX idx_Restricted ON Restricted (fk_id, fk_foo)
一旦指数存在;任何可能从中受益的查询都会在后台自动使用它;你不需要为它调整查询。
侧面说明;因为你显然在寻找产品我觉得很奇怪你没有把注意力集中在Products
上。
SELECT p.name
FROM Products p
JOIN etc...