我尝试优化查询,因为它需要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
答案 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
,同时,由于DESC
和ASC
的混合,需要进行排序。