需要一个简单的solutin来减慢查询速度

时间:2016-01-05 21:53:28

标签: 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.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)出售

以上查询可以优化吗?它需要2分钟才能运行1100万条记录。

由于

3 个答案:

答案 0 :(得分:1)

您多久会使用一次特定的“前缀”?如果经常这样,那么我将指导您索引“虚拟”列。

否则,您需要

RewriteEngine On
RewriteRule ^/gui/?(.*)$ /webui/index.php?shell_file=$1 [R,L,QSA]

然后按照建议执行INDEX(date) -- for the outer query INDEX(dealer_id, date) -- for what is now the subquery ,或使用EXISTS

LEFT JOIN ... WHERE ... IS NULLdate吗?还是DATE?您可能需要额外一天。建议这种模式:

DATETIME

答案 1 :(得分:0)

如果你想要一个简单的解决方案,我最初的想法是想办法在你的连接中没有函数调用。

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

(concat(substr(h.vin,1,8),'_',substr(h.vin,10,3))=vd.prefix)

也许一个like语句会更好,但是,要避免连接子句中的任何一种方法。

底线是你的桌子结构&amp;这里的关系留有改进的余地...如果您需要concat,因为您要避免加入中间表,请不要 - 允许使用索引,它应该可以提高您的查询性能。

另外,请确保您有索引。

答案 2 :(得分:0)

我建议3件事

  1. 添加一个列并将其编入索引(避免连接中的函数)
  2. 使用内部联接
  3. 使用EXISTS(...)代替IN(...)
  4. 要“优化”该查询,您需要向表Public Class Form1 Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click If (IsNumeric(txtSale.text) And IsNumeric(txtSalesTaxRate.text)) Then lblTax.text= cint(txtSale.text) * cint(txtSalesTaxRate.text) lblTotal.text= cint(txtSale.text) + cint(lblTax.text) Else MsgBox("Please enter valid numbers, thank you!") End If End Sub End Class 添加一列,其中包含car_history_optimized的结果,此列应编入索引。

    另外,使用INNER JOIN。在当前查询中,左外连接被浪费,因为您要求该表的每一行都是IN(子查询),因此不允许该表中的NULL,因此您具有与内连接相同的效果。

    使用EXISTS代替IN

    concat(substr(vin,1,8),'_',substr(vin,10,3))

    顺便说一下:

    • 我假设已经有一些索引,其中包括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 ) ; date
    • 将来避免使用“日期”作为列名(它是保留字)