0

わかりました、次の人が一日中私を悩ませてきました:

以下のクエリを使用して、別のテーブル(tresults)のフィールドStartTimeに基づいて、最新の結果価格を含む製品と価格の概要を選択します。これを行うには、結合に副選択が必要だと思いました。

問題は、EXPLAIN関数が、MySQLがインデックスを使用せずにすべての結果行(225000行)をスキャンしていることを通知していることです。

これをスピードアップする方法はありますか?できれば、WHEREステートメントを追加して、mysqlが対応するpIDを持つ行のみを参照するようにします。

select p.pID, brandname, description, p.EAN, RetailPrice, LowestPrice, min(price), min(price)/lowestprice-1 as afwijking
from tproducts p
    join ( 
    select Max(tresults.StartTime) AS maxstarttime, tresults.pID
    from tresults
    -- maybe adding a where clause here?
    group by tresults.pID
    ) p_max on (p_max.pID = p.pID)
join tresults res on (res.starttime = p_max.maxstarttime and p.pID = res.pID and res.websiteID = 1)
join tsupplierproducts sp on (sp.pID = p.pID AND supplierID = 1)
join tbrands b on (b.brandID = p.BrandID)
group by p.pID, brandname, description, p.EAN, RetailPrice, LowestPrice

インデックスは、結合またはwhere句の一部であるすべての列にあります。

どんな助けでもいただければ幸いです。ありがとう!

4

1 に答える 1

0

SQLから、1つのサプライヤ(supplierID = 1)のみに基づいて製品をリストしていると仮定します。

ベストプラクティスは、SQLの先頭で既知のフィルターを実行してレコードを削除してから、内部結合を使用してフィルターテーブルなしで他の結合を実行することです。

select p.pID, brandname, description, p.EAN, RetailPrice, LowestPrice, min(price), min(price)/lowestprice-1 as afwijking
from 
(select p.pID, p.BrandID p.EAN, Max(t.StartTime) AS maxstarttime
FROM tproducts p INNER JOIN tresults t on supplierID=1 and p.pID=t.pID
group by tresults.pID
) p 
inner join tresults res on (res.websiteID = 1 and p.pID = res.pID and res.starttime = p_max.maxstarttime)
inner join tsupplierproducts sp on (sp.pID = p.pID)
inner join tbrands b on (b.brandID = p.BrandID)
group by p.pID, brandname, description, p.EAN, RetailPrice, LowestPrice

上記のコードから、tresultsに参加する前に、tproductsからすべてのsupplierID!=1を削除します。

上記のSQLが役立つかどうか、およびEXPLAIN関数の結果は何ですか?

:-)

于 2012-09-27T09:59:42.670 に答える