【问题标题】:optimize sql multiple left join and where clause优化sql多左连接和where子句
【发布时间】:2014-07-21 06:46:36
【问题描述】:
SELECT distinct text FROM oc_product_attribute as pa
LEFT JOIN oc_product_to_category as ptc ON  pa.product_id = ptc.product_id
LEFT JOIN oc_product as p ON pa.product_id = ptc.product_id
WHERE p.status = 1 AND ptc.category_id = 61 
GROUP BY pa.text LIMIT 10

尽管我使用 LIMIT,但我的数据库挂起上述查询。有什么办法优化吗?

【问题讨论】:

  • 使用前 10 名而不是限制。
  • 您是否在要加入的列上使用索引?
  • @DH__ - TOP 不是 LIMIT 的 SQL 版本吗?这是 MySQL。请注意,除非pa.text 被索引(并且优化器足够聪明/可以利用它),否则数据库必须获取所有行,对它们进行排序,然后选择所需的 10/throw其他一切都消失了。
  • 您的 WHERE 子句将 LEFT JOIN 更改为 INNER JOIN,因为它的条件检查 LEFT JOINed 表的字段。如果这不是您的意图,请将这些条件移至相应的 ON 子句。此外,您应该使用 EXPLAIN 并将结果与​​ SHOW CREATE TABLE 的结果一起发布在这里
  • 你为什么使用DISTINCT textGROUP BY pa.text。两者都试图在这里做同样的事情。文本列是什么数据类型?

标签: mysql sql


【解决方案1】:

在这一行中,您应该使用别名 p 而不是 ptc

LEFT JOIN oc_product as p ON pa.product_id = ptc.product_id

应该是

LEFT JOIN oc_product as p ON pa.product_id = p.product_id

【讨论】:

  • 也许你应该解释一下为什么这会导致他的声明挂起?
  • 根据我的数据库设计这是不可能的
  • “不可能”是什么意思?在您构建交叉产品的那一刻,意味着您从第一次加入 oc_product 开始加入每条记录。这会产生更多你想要的线条。请添加表的创建语句。
【解决方案2】:

我认为此查询中不需要DISTINCTGROUP BY,因为无论如何您都在 where 子句中使用这两个表。还因为您只是选择文本列。您可以考虑将查询重写为:

SELECT 
    pa.text 
FROM 
    oc_product_attribute as pa
WHERE EXISTS
(
    SELECT
        NULL
    FROM
        oc_product_to_category as ptc 
        JOIN oc_product as p 
            ON p.product_id = ptc.product_id
    WHERE  
        pa.product_id = ptc.product_id
        AND p.status = 1 
        AND ptc.category_id = 61
)
LIMIT 10

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    相关资源
    最近更新 更多