优化查询-mysql

优化查询-mysql,mysql,optimization,myisam,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(`pro

我试图优化我的查询,因为它需要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(求和(
products\u 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

我不确定引入用户变量会有多大变化。但是有条理地在两个表上添加索引可能会有所帮助。试试这个:

ALTER TABLE products ADD INDEX nurse_index (nurseForm);
ALTER TABLE products_uses ADD INDEX product_index (productId);
products.nurseForm
列上的第一个索引可能有助于
WHERE
子句。特别是,如果只有少数记录匹配,这个索引将是一个很大的帮助

第二个索引位于
products\u uses.productId
,可能有助于加快加入速度。同样,这取决于您的桌子有多大


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

我不确定引入用户变量会有多大变化。但是有条理地在两个表上添加索引可能会有所帮助。试试这个:

ALTER TABLE products ADD INDEX nurse_index (nurseForm);
ALTER TABLE products_uses ADD INDEX product_index (productId);
products.nurseForm
列上的第一个索引可能有助于
WHERE
子句。特别是,如果只有少数记录匹配,这个索引将是一个很大的帮助

第二个索引位于
products\u uses.productId
,可能有助于加快加入速度。同样,这取决于您的桌子有多大


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

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

这可能会(也可能不会)有帮助。它尝试在不拖拉
产品的所有列的情况下进行求和。它避免了按
分组

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可以通过帮助处理
订单,同时,由于
DESC
ASC
的混合,需要进行排序,提供
SHOW CREATE TABLE
会有所帮助。同时,我猜

这可能会(也可能不会)有帮助。它尝试在不拖拉
产品的所有列的情况下进行求和。它避免了按
分组

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可以帮助按
排序,同时,由于混合了
DESC
ASC

1,因此需要进行排序。用2检查查询计划。确定运行时间较长的第3部分,尝试对其进行优化(如何优化取决于解释结果)。如果时间在优化后不合适,那么返回1作为第一种方法,我会添加products.productQuantity在WHERE子句上不为NULL,这样可以避免检索它们并执行ifnullWhat版本的MySQL?1。用2检查查询计划。确定运行时间较长的第3部分,尝试对其进行优化(如何优化取决于解释结果)。如果优化后时间不合适,返回1作为第一种方法,我会添加products.productQuantity在WHERE子句上不为NULL,这样可以避免检索它们并执行ifnullWhat版本的MySQL?