Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 为什么查询不使用索引以及如何优化它?_Mysql_Sql_Optimization_Indexing_Key - Fatal编程技术网

Mysql 为什么查询不使用索引以及如何优化它?

Mysql 为什么查询不使用索引以及如何优化它?,mysql,sql,optimization,indexing,key,Mysql,Sql,Optimization,Indexing,Key,我有一个运行114秒的SQL查询。该表包含224000行 为什么不使用“产品”表的键 有人知道如何优化这个查询吗 EXPLAIN SELECT SUM( quantity * ( SELECT IF( netoweight = '', weight, netoweight ) AS weight FROM products WHERE product_nr = it.item ) /1000 ) FROM `inventory_transactions` it WHERE it.type

我有一个运行114秒的SQL查询。该表包含224000行

为什么不使用“产品”表的键

有人知道如何优化这个查询吗

EXPLAIN SELECT SUM( quantity * ( 
SELECT IF( netoweight =  '', weight, netoweight ) AS weight
FROM products
WHERE product_nr = it.item ) /1000 ) 
FROM  `inventory_transactions` it
WHERE it.type =  'Production'
AND it.item >  '200000'
AND it.item <  '400000'
AND it.date LIKE  '2013-01%'
AND (
(

SELECT COUNT( id ) 
FROM structure
WHERE final_item = it.item
AND level >  '1'
) <1
)

MySQL在优化这样的子查询方面非常糟糕,所以如果可能的话,您必须稍微帮助它,使用连接重写它。对于第一个子查询,这应该很容易:

SELECT SUM( quantity * weight /1000 ) 
FROM  `inventory_transactions` it
JOIN (SELECT product_nr, IF( netoweight =  '', weight, netoweight ) AS weight
     FROM products) AS products
ON product.product_nr = it.item
WHERE it.type =  'Production'
AND it.item >  '200000'
AND it.item <  '400000'
AND it.date LIKE  '2013-01%'
AND (
(

SELECT COUNT( id ) 
FROM structure
WHERE final_item = it.item
AND level >  '1'
) <1
)
但是,由于第二个查询更复杂,因此这可能还不能解决不在产品表上使用键的问题。但是,应通过以下方式使用group by对其进行重写:

SELECT SUM( quantity * weight /1000 ) 
FROM  `inventory_transactions` it
JOIN (SELECT product_nr, IF( netoweight =  '', weight, netoweight ) AS weight
     FROM products) AS products,
ON product.product_nr = it.item
LEFT OUTER JOIN (SELECT final_item, COUNT( id ) AS count
    FROM structure
    WHERE level > '1'
    GROUP BY final_item) AS struct_count
ON it.item = struct_count.final_item
WHERE it.type =  'Production'
AND it.item >  '200000'
AND it.item <  '400000'
AND it.date LIKE  '2013-01%'
AND struct_count.count IS NULL

结构计数为0的产品需要IS NULL部分,因为它们在联接中不匹配。对于查询处理程序来说,使用适当的索引应该更容易执行此查询。如果它仍然不使用它们,请检查它们是否位于正确的列中。

第一次连接将执行时间从114秒增加到3.5秒。非常感谢你。我会尝试你的答案的后半部分,稍后再发布结果。啊,很好!我很惊讶,虽然那是罪魁祸首。您是否可以只尝试第二次优化而不尝试第一次优化?只是为了得到所有的数字,这会很有趣:我现在在不同的月份运行查询,结果如下。我最初的疑问是:197s。您的第一个查询:0.48s。没有第一个联接的第二个查询:花费太多时间并挂起。使用联接和左外部联接的第二个查询:0.45s。非常好的优化:。非常感谢@inflagranti!
SELECT SUM( quantity * weight /1000 ) 
FROM  `inventory_transactions` it
JOIN (SELECT product_nr, IF( netoweight =  '', weight, netoweight ) AS weight
     FROM products) AS products,
ON product.product_nr = it.item
LEFT OUTER JOIN (SELECT final_item, COUNT( id ) AS count
    FROM structure
    WHERE level > '1'
    GROUP BY final_item) AS struct_count
ON it.item = struct_count.final_item
WHERE it.type =  'Production'
AND it.item >  '200000'
AND it.item <  '400000'
AND it.date LIKE  '2013-01%'
AND struct_count.count IS NULL