0

私は2つのテーブルを持っています Invoice( Id, Status, VendorId, CustomerId, OrderDate, InvoiceFor)

InvoiceItem( Id, Status, InvoiceId, ProductId, PackageQty, PackagePrice)

ここでは、invoice.id=invoiceItem.invoiceId (Foregin キー) および Id フィールドは主キー (big int) です。これらのテーブルには、100000 (invoice) および 450000 (invoiceItem) 行が含まれます。


ここで、特定の日付範囲の請求書 = 55 または 66 の請求書の元帳を返すクエリを作成する必要があります。また、その特定の顧客による製品の前回の撮影日を含む最終撮影日を返す必要があります。


出力は、OrderDate、InvoiceId、CustomerId、ProductId、LastTaken、PackageQty、PackagePrice である必要があります。


だから私は次のクエリを書きます

SELECT a.*, (
    SELECT MAX(ivv.orderdate)
    FROM invoice AS ivv , invoiceItem AS iiv 
    WHERE ivv.id=iiv.invoiceid
    AND iiv.ProductId=a.ProductId AND ivv.CustomerId=a.CustomerId AND ivv.orderDate<a.orderdate
) AS lastTaken FROM (
    SELECT iv.Id, iv.OrderDate, iv.CustomerId, iv.InvoiceFor, ii.ProductId,     
    ii.PackageQty, ii.PackagePrice
    FROM invoice AS iv, invoiceitem AS ii
    WHERE iv.id=ii.InvoiceId 
    AND iv.InvoiceFor IN (55,66)
    AND iv.Status=0 AND ii.Status=0 
    AND OrderDate BETWEEN '2011-01-01' AND '2011-12-31'
    ORDER BY iv.orderdate, iv.Id ASC 
) AS a

しかし、私はいつもタイムアウトを得ました。どうすれば問題を解決できますか???

このクエリの Explain は次のとおりです。 ここに画像の説明を入力

4

2 に答える 2

0

クエリ自体に関する 2 つのポイント:

  1. 適切な JOIN 構文の使用方法を学びます。句で結合を行うことはWHERE、シェイクスピアの英語で質問を書くようなものです。
  2. サブクエリのORDER BYは、最高レベルで外側にある必要があります。

ただし、どちらもパフォーマンスを低下させるものではありません。問題は、SELECT句のサブクエリです。問題は、SELECT句のサブクエリが 2 つのテーブルを直接結合していないことだと思います。iiv.InvoiceId = ivv.InvoiceIdin、できればandON句を含めてみてください。

それでもうまくいかない場合は、インデックス作成戦略を試してください。次のインデックスは、そのサブクエリのパフォーマンスを向上させるはずです。

  • InvoiceItem(ProductId) のインデックス
  • Invoice のインデックス (CustomerId、OrderDate)

これにより、MySQL は完全なテーブル スキャンではなくインデックスからサブクエリを実行できるようになり、パフォーマンスが大幅に向上するはずです。

于 2012-10-07T19:15:01.957 に答える
0

OrderDate および InvoiceFor 属性にインデックスを作成します。それははるかに速いはずです。

于 2012-10-07T13:36:14.327 に答える