Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.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_Mysql Slow Query Log - Fatal编程技术网

Mysql 需要一个简单的解决方案来减缓查询速度

Mysql 需要一个简单的解决方案来减缓查询速度,mysql,sql,mysql-slow-query-log,Mysql,Sql,Mysql Slow Query Log,我有以下疑问 SELECT avg(h.price) FROM `car_history_optimized` h LEFT JOIN vin_data vd ON (concat(substr(h.vin,1,8),'_',substr(h.vin,10,3))=vd.prefix) WHERE h.date >='2015-01-01' AND h.date <='2015-04-01' AND h.dealer_id <> 2389 AND vd.pre

我有以下疑问

SELECT avg(h.price)
FROM `car_history_optimized` h
LEFT JOIN vin_data vd ON (concat(substr(h.vin,1,8),'_',substr(h.vin,10,3))=vd.prefix)
WHERE h.date >='2015-01-01'
  AND h.date <='2015-04-01'
  AND h.dealer_id <> 2389
  AND vd.prefix IN
    (SELECT concat(substr(h.vin,1,8),'_',substr(h.vin,10,3))
     FROM `car_history_optimized` h
     LEFT JOIN vin_data vd ON (concat(substr(h.vin,1,8),'_',substr(h.vin,10,3))=vd.prefix)
     WHERE h.date >='2015-03-01'
       AND h.date <='2015-04-01'
       AND h.dealer_id =2389)
它可以找到除2389以外的所有人在过去3个月内售出的汽车的平均市场价值,但只有那些拥有相同品牌、型号的汽车在2389年售出

上面的查询可以优化吗?运行1100万条记录需要2分钟


谢谢

如果您想要一个简单的解决方案,我最初的想法是找到一种在联接中不进行函数调用的方法

您会对索引有帮助的可能性产生负面影响

(concat(substr(h.vin,1,8),'_',substr(h.vin,10,3))=vd.prefix)
也许使用like语句会更好,但是,join子句中的任何一种方法都应该避免

底线是您的表结构和关系,这里有改进的余地。。。如果因为避免连接中间表而需要concat,请不要使用索引,这样可以提高查询性能

另外,确保您有索引

我建议三件事

添加列并对其进行索引,以避免连接中的函数 使用内部连接 使用存在。。。而不是在。。。 要优化该查询,您需要将一列添加到car_history_optimized表中,该表包含concatsubstrvin,1,8、“_”、substrvin,10,3的结果,并且该列应该被索引

另外,使用内部联接。在当前查询中,左外部联接是浪费的,因为您要求该表的每一行都位于子查询中,因此不允许该表中的NULL,因此具有与内部联接相同的效果

使用存在,而不是在中

SELECT
      AVG(h.price)
FROM car_history_optimized h
      INNER JOIN vin_data vd ON h.new_column = vd.prefix
WHERE h.`date` >= '2015-01-01'
      AND h.`date` <= '2015-04-01'
      AND h.dealer_id <> 2389
      AND EXISTS (
            SELECT
                  NULL
            FROM car_history_optimized cho
            WHERE cho.`date` >= '2015-03-01'
                  AND cho.`date` <= '2015-04-01'
                  AND cho.dealer_id = 2389
                  AND vd.prefix = cho.new_column
      )
;
顺便说一下:

我假设已经有了一些索引,其中包括日期和经销商id 以后避免使用date作为列名,这是一个保留字
您将多久使用一次该前缀?如果经常,那么我将指导您为“虚拟”列编制索引

否则,你需要

INDEX(date)             -- for the outer query
INDEX(dealer_id, date)  -- for what is now the subquery
然后按建议执行EXISTS,或使用左联接。。。哪里是空的

约会是约会吗?还是约会时间?您可能需要额外的一天。建议这种模式:

WHERE date >= '2015-01-01'
  AND date  < '2015-01-01' + INTERVAL 3 MONTH

在设置查询格式方面花些功夫。从所有concat创建一个新列并加入其中,这可能会加快查询速度。可能只是我,但我觉得可以删除vin_数据上的加入。您似乎只对concat的结果感兴趣,而不使用来自vin_数据的任何其他值。谢谢您的建议。正如您所说,我在历史记录表中添加了新字段,还添加了索引。但是这个查询变得更慢了。实际上,它在过去5分钟内从未给出任何结果,仍然在执行..该建议应该会提高性能,但您确实需要在两个表vd.prefix和h.new_列上使用该索引。您应该考虑两个表是如何被索引的,并运行执行计划来观察它们是否被使用。Dead字段是日期而不是DATETIME。我已经有了date的索引,但没有索引交易商id datefrank,我在历史记录表中添加了新列,从查询中删除了concatsubstr函数,也为新列编制了索引,但没有任何改进。查询更慢