【问题标题】:Optimize query - mysql优化查询——mysql
【发布时间】:2018-12-21 13:59:39
【问题描述】:

我尝试优化我的查询,因为它需要 3.5 秒而且太长了。 这是我的查询:

SELECT
`products`.*,
IFNULL(SUM(`products_uses`.`quantity`),0) as `usesQuantity`,
IF((`products`.`productQuantity` - IFNULL(SUM(`products_uses`.`quantity`),0)) > 0, (`products`.`productQuantity` - IFNULL(SUM(`products_uses`.`quantity`),0)), 0) AS `totalUses`
FROM `products`
LEFT JOIN `products_uses` ON `products`.`id` = `products_uses`.`productId`
WHERE `products`.`nurseForm` = 1
GROUP BY `products`.`id`
ORDER BY `products`.`fav` DESC, `products`.`productName` ASC

我尝试使用变量进行优化,但没有任何改变:

SELECT
`products`.*,
@usesQuantity := IFNULL(SUM(`products_uses`.`quantity`),0) as `usesQuantity`,
IF((`products`.`productQuantity` - @usesQuantity) > 0, (`products`.`productQuantity` - @usesQuantity), 0) AS `totalUses`
FROM `products`
LEFT JOIN `products_uses` ON `products`.`id` = `products_uses`.`productId`
WHERE `products`.`nurseForm` = 1
GROUP BY `products`.`id`
ORDER BY `products`.`fav` DESC, `products`.`productName` ASC

这个查询 总结每种产品的使用量 - IFNULL(SUM(products_uses.quantity),0) , 每种产品的使用量 -

IF((`products`.`productQuantity` - IFNULL(SUM(`products_uses`.`quantity`),0)) > 0, (`products`.`productQuantity` - IFNULL(SUM(`products_uses`.`quantity`),0)), 0)

我尝试将表的结构更改为 myISAM 和 InnoDB,但没有任何改变。 我能做些什么来优化这个查询? tnx

【问题讨论】:

  • 1.使用explain 检查查询计划 2. 确定运行时间较长的第 3 部分,尝试对其进行优化(如何取决于解释结果) 4. 如果优化后时间不合适,请返回 1 作为第一种方法,我会添加产品。 productQuantity IS NOT NULL on WHERE 子句,这样可以避免检索它们并执行 ifnull
  • 什么版本的 MySQL?

标签: mysql optimization myisam


【解决方案1】:

提供SHOW CREATE TABLE 会有所帮助。同时,我猜。

这可能会(也可能不会)有帮助。它试图在不拖拽products 的所有列的情况下进行求和。它避免了GROUP BY。

SELECT  p2.*,
        IFNULL(x.usesQuantity, 0) as `usesQuantity`,
        GREATEST(p2.`productQuantity` - IFNULL(x.usesQuantity), 0) AS `totalUses`
    FROM  `products` AS p2
    LEFT JOIN  
        ( SELECT  p.id AS xid,
                  SUM(pu.quantity) as `usesQuantity`
            FROM  products_uses AS pu
            JOIN  products AS p  ON p.id = pu.productId
            WHERE  p.nurseForm = 1 
        ) AS x  ON x.xid = p2.id
    ORDER BY  p2.`fav` DESC,
              p2.`productName` ASC

这些索引应该会有所帮助:

products:  INDEX(nurseForm, id)
products:  PRIMARY KEY(id)  -- I am assuming this??
products_uses:  INDEX(productId, quantity)

如果LEFT 是不必要的,就会有其他优化。

MySQL 5.6 将有助于子查询。
MySQL 8.0 可以帮助处理ORDER BY,同时,由于DESC 和ASC 的混合,需要进行排序。

【讨论】:

    【解决方案2】:

    我不确定引入用户变量会改变多少。但是在你的两个表上添加索引可能会有所帮助。试试这个:

    ALTER TABLE products ADD INDEX nurse_index (nurseForm);
    ALTER TABLE products_uses ADD INDEX product_index (productId);
    

    products.nurseForm 列上的第一个索引可能有助于 WHERE 子句。特别是,如果只有少数记录匹配,此索引​​将有很大帮助。

    products_uses.productId 上的第二个索引可能有助于加快连接速度。同样,这取决于您的表有多大。

    您也可以运行EXPLAIN 以查看是否有其他瓶颈突出。

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 2011-07-07
      • 2010-12-15
      • 2011-11-04
      • 2016-01-25
      • 2023-03-19
      相关资源
      最近更新 更多