2016-11-02 11 views
0

MySQLのSQLクエリに問題があります。それを最適化する方法についてあなたの助けに感謝します。あなたはどんな歴史の日付に関連する請求書を生成することができるように基本的に、それは、いくつかの製品の歴史的な価格を保持しているSQLクエリに時間がかかりすぎるテンポラリーテーブル

price_id int(5) Primary Key with auto increment 
product_id int(5) 
price_amount float 
price_date date 

問題のクエリは次のようになります周りの8000行を持つテーブル上で実行されます。

問題のある質問は、特定の日付に関連する製品のリストの最新の価格を私に与える必要があります。例えば、9月1日までとしてのproduct_id 1、2及び4の関連する価格を得るために、それは次のようになります。

SELECT * 
FROM prices 
WHERE price_id IN (
    SELECT max(prices.price_id) 
    FROM prices 
    WHERE product_id in (1,2,4) AND price_date <= '2016-09-01' 
    GROUP BY product_id 
) 

さて、このクエリはaaaaaagesのために実行されます。それはさまざまですが、今のところ、例えば3つのproduct_idsについては、実行に約58秒かかりました。それらの中に〜約120の製品を持っている(結果を返すために数分かかります)ので、あなたがトラブルを想像することができます。..

通常の請求書には、私は、phpMyAdminの中でクエリをプロファイリングし、基本的には次のようになります。

Status      Time 
Sorting result    0.000050 
Sending data     0.000025 
executing      0.000009 
Copying to tmp table   0.008586 
Sorting result    0.000052 
Sending data     0.000026 
executing      0.000006 
Copying to tmp table   0.008118 
Sorting result    0.000057 
Sending data     0.000029 
executing      0.000011 
Copying to tmp table   0.007498 
Sorting result    0.000047 
Sending data     0.000021 
executing      0.000005 
Copying to tmp table   0.008479 
Sorting result    0.000056 
Sending data     0.000031 
executing      0.000011 
Copying to tmp table   0.007371 
Sorting result    0.000059 
Sending data     0.000031 
executing      0.000011 
Copying to tmp table   0.006702 
Sorting result    0.000045 
Sending data     0.000019 
executing      0.000005 
Copying to tmp table   0.005319 
Sorting result    0.000034 
Sending data     0.000015 
executing      0.000005 
Copying to tmp table   0.005302 
Sorting result    0.000035 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005207 
Sorting result    0.000031 
Sending data     0.000014 
executing      0.000005 
Copying to tmp table   0.005243 
Sorting result    0.000034 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005236 
Sorting result    0.000035 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005185 
Sorting result    0.000035 
Sending data     0.000015 
executing      0.000005 
Copying to tmp table   0.005256 
Sorting result    0.000033 
Sending data     0.000017 
executing      0.000005 
Copying to tmp table   0.005160 
Sorting result    0.000025 
Sending data     0.000014 
executing      0.000005 
Copying to tmp table   0.005149 
Sorting result    0.000024 
Sending data     0.000013 
executing      0.000005 
Copying to tmp table   0.005356 
Sorting result    0.000038 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005221 
Sorting result    0.000034 
Sending data     0.000016 
executing      0.000005 
Copying to tmp table   0.005189 
Sorting result    0.000033 
Sending data     0.000015 
executing      0.000005 
Copying to tmp table   0.005370 
Sorting result    0.000038 
Sending data     0.000017 
executing      0.000005 
Copying to tmp table   0.005208 
Sorting result    0.000035 
Sending data     0.000017 
executing      0.000006 
Copying to tmp table   0.005209 
Sorting result    0.000036 
Sending data     0.000054 
end       0.000019 
removing tmp table   0.000021 
end       0.000008 
query end      0.000006 
closing tables    0.000020 
freeing items     0.000052 
Waiting for query cache lock 0.000006 
freeing items     0.000852 
Waiting for query cache lock 0.000012 
freeing items     0.000004 
storing result in query cache 0.000019 
logging slow query   0.000005 
logging slow query   0.000010 
cleaning up     0.000009 

Showing rows 0 - 2 (3 total, Query took 58.6074 sec) 

数字で推測すると、ほとんどの場合、一時テーブルの作成に費やされます。 (ヒープとテンポラリ・テーブルの最大サイズ・パラメータは、16Mのデフォルト値です)。

誰も私がこのクエリをスピードアップすることができますか、または同じよりはるかに効率的に新しいクエリを設計することができますか?

+0

クエリの最適化とリレーショナル代数! –

答えて

0

(から動のを使用してみてください)、内側は結果のテーブルに参加

select * from prices as a 
    inner join (  
     SELECT max(prices.price_id) as max_price_id 
     FROM prices 
     WHERE product_id in (1,2,4) AND price_date <= '2016-09-01' 
     GROUP BY product_id) t on t.max_price_id = a.price_id 
0

相関クエリを使用して、あなたがに自由であるならば、時にはmysqlのは、INサブクエリ

SELECT prices.* 
FROM prices 
WHERE EXISTS (
    SELECT max(p.price_id) 
    FROM prices p 
    WHERE p.product_id in (1,2,4) AND p.price_date <= '2016-09-01' 
    AND prices.price_id = p.price_id 
    GROUP BY p.product_id 
) 
0

に問題がありますインデックスを追加し、product_id、(2)price_date(降順)でテーブルのインデックスを作成します。

SELECT * 
FROM prices 
WHERE product_id in (1,2,4) AND price_date <= '2016-09-01' 
ORDER BY price_date DESC 
LIMIT 1 
+0

それは単一の製品を返すものではないでしょうか? 3つすべての製品の価格が必要です – Odesh

関連する問題