优化查询-MySQL

时间:2018-07-13 08:28:38

标签: mysql optimization myisam

我尝试优化查询,因为它需要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 .数量),0) , 每种产品的使用量-

IF((`products`.`productQuantity` - IFNULL(SUM(`products_uses`.`quantity`),0)) > 0, (`products`.`productQuantity` - IFNULL(SUM(`products_uses`.`quantity`),0)), 0)
我试图将表的结构更改为myISAM和InnoDB,但没有进行任何更改。 我该怎么做才能优化此查询? tnx

2 个答案:

答案 0 :(得分: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来查看是否还有其他瓶颈。

答案 1 :(得分:0)

提供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,同时,由于DESCASC的混合,需要进行排序。