2012-06-05 37 views
0

我不是sql的专家,我需要以下查询的帮助。它很差,执行时间也很长。 是否有可能用JOIN()替换IN()以加快查询速度? 如何做到这一点?Mysql查询优化不佳

SELECT * 
FROM shop_orders 
WHERE id IN (SELECT orders_id 
       FROM shop_orders_data 
       WHERE closed = '1' /*AND backorder='0'*/) 
     AND id IN (SELECT orders_id 
        FROM shop_orders_products 
        WHERE products_id IN (SELECT id 
             FROM shop_products 
             WHERE artno = '120000' 
               OR name LIKE '%120000%')) 
ORDER BY created DESC 
+0

是的,这是可能的。 –

+2

尝试添加您的表格结构和关键关系到您的文章(并接受您以前的问题的答案)。 – Crontab

回答

1
Select so.* 
from shop_orders as so 
    join shop_orders_data as sod on sod.orders_id = so.id 
    join (select orders_id 
      from shop_orders_products as sop 
        join shop_products as sp on sp.id = sop.products_id 
      where sp.artno = '120000' 
        OR sp.name like '%120000%') as sop on sop.orders_id = so.id 
where 
    sod.closed = '1' 
order by so.created desc 
+0

只需更新它,让您加入已经减少的查询结果。这应该使联接操作更快,因为它将有更少的行要通过。 这里的主要想法是,在您的第一个查询中,您有效地对表中的每一行执行查询。在这里,您将执行合并操作,然后查询表以查看它是否符合where子句中指定的条件。 – cDecker32

+0

查询中有一个额外的“)”。工作正常!谢谢! – Oualid

+0

糟糕。对于那个很抱歉。希望它能帮助你更好地理解查询。 – cDecker32

1

是的,你是在正确的道路上 - 你可以只是所有这些表,而不是这些在运营商之间的内部连接。

SELECT 
    so.* 
FROM 
    shop_orders so 
    INNER JOIN shop_orders_data sod 
     ON so.id = sod.orders_id 
    INNER JOIN shop_orders_products sop 
     ON sod.id = sop.orders_id 
    INNER JOIN shop_products sp 
     ON sop.products_id = sp.id 
WHERE sod.closed = '1' 
    AND (sp.artno = '120000' OR sp.name LIKE '%120000%') 
+4

隐式连接是一个sql反模式,不应在解决方案中推荐。 – HLGEM

+0

已更新为显式,但我不同意将隐式连接描述为反模式。 –

+0

这很好。它可能需要'GROUP BY so.id'来删除重复的结果。 –

2

我想这应该这样做:

SELECT 
    s.* 
FROM 
    shop_orders s 
INNER JOIN 
    shop_orders_data od 
ON 
    s.id=od.orders_id 
INNER JOIN 
    shop_orders_products sop 
ON 
    s.id=sop.orders_id 
INNER JOIN 
    shop_products sp 
ON 
    sop.products_id=sp.id 
WHERE 
    od.closed=1 
AND 
    (sp.artno='120000' or sp.name LIKE '%120000%') 
3

我要说喜欢的是这里造成的最大延迟......将在货号不够? LIKE通常是一个非常昂贵的过程。

+0

当你喜欢将通配符作为第一个字符时,索引不能有效使用。 – HLGEM

+0

谢谢!现在它快得多。 – Oualid