-2

次のクエリがあります..

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)

過去 3 か月以内に (2389) 以外のすべての人によって販売された車の平均市場価値を見つけますが、(2389) によって販売された同じメーカー、モデルの車のみです。

上記のクエリを最適化できますか? 1,100 万レコードの実行に 2 分かかります。

ありがとう

4

3 に答える 3

0

簡単な解決策が必要な場合、私が最初に考えたのは、結合で関数呼び出しを行わないようにする方法を見つけることです。

インデックスが役立つ可能性に悪影響を及ぼします。

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

likeステートメントの方が良いアイデアかもしれませんが、結合句でのどちらのアプローチも避ける必要があります。

要点は、テーブルの構造と関係です。ここでの関係には改善の余地があります...concat中間テーブルの結合を避けているために必要な場合は、インデックスの使用を許可しないでください。クエリのパフォーマンスが向上するはずです。

また、インデックスがあることを確認してください。

于 2016-01-05T21:58:10.603 に答える
0

3つのことを提案します

  1. 列を追加してインデックスを作成します(結合の関数を避けます)
  2. 内部結合を使用する
  3. IN (...) の代わりに EXISTS (...) を使用する

そのクエリを「最適化」するにcar_history_optimizedは、結果を含むテーブルに列を追加する必要がありconcat(substr(vin,1,8),'_',substr(vin,10,3))、この列にインデックスを付ける必要があります。

また、INNER JOIN を使用します。現在のクエリでは、そのテーブルのすべての行を IN (サブクエリ) にする必要があるため、左外部結合が無駄になり、そのテーブルからの NULL は許可されないため、内部結合と同じ効果があります。

IN の代わりに EXISTS を使用する

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とが含まれていると思いますdealer_id
  • 今後、「日付」を列名として使用しないようにします (これは予約語です)。
于 2016-01-06T00:00:01.700 に答える