2012-04-24 1 views
0

私はうまくいきましたこのクエリを持っています。別の主キー索引に変更すると、このクエリでパフォーマンスが低下するのはなぜですか?

SELECT SUM(amount) FROM company.invoice_line WHERE item_id != shipping 
    AND item_id != '' 
    AND invoice_id IN 
     (SELECT id_invoices FROM company.invoices WHERE customer = 'XX' 
      AND sales_rep = 'XXX'); 

目的は、顧客からすべての担当者の売上高を合計することです。 顧客およびの代理人のデータは、invoiceテーブルに関連付けられ、invoiceテーブルに関連するテーブルinvoice lineに関連付けられて格納されます。私が働いているデータのサイズについては

、クエリを約0.015s

を取る私はVARCHARた別のPKでクエリでid_invoicesを変更しましたが、独自のフラグを立てたりするものではないではありません。

理由は手前だったので、私はinvoiceがDBに挿入されるという凶悪な設計をしていましたが、invoiceの自動インクリメントされたPKに外部キーとして使用するよう求めるクエリが直ちに続きます。

BULK INSERTを効果的に使用するには、自動増分された「バニラ」INT PKに依存せずに、実質的にすべての自分のデータに固有の識別子にアクセスする必要がありました。上記のようにして、外来キーなどとして役立つ列を追加することでこれを達成しました。

私の挿入率は今すぐ素晴らしいですが、になりました。になりました。

手前で、バニラの自動インクリメントintをPKとして使用していました。外部キーをVARCHARに切り替えると、パフォーマンスが大幅に低下しますか?

私の次の動きは、int idのものに戻っているようですが、手動でこれらのintインデックスを手動で作成するためにMySQLが自動インクリメントを許可するのではなく、一括挿入を使用できます。クエリの観点からは、それは重要ではありません...それは必要ですか?

ご協力いただければ幸いです。

デーン

+2

各クエリの最適化は、 'EXPLAIN'で始まります。 – zerkms

答えて

1

さて、まずあなたが変更された可能性がある他に何を参照するには、クエリプランで何が起こっているかを判断するために、EXPLAINを使用する必要があります。

第2に、VARCHAR列の方がINT列よりも遅くなりますが、一般的に定数は増加します(たとえば、kがnに関連しない場合はk * O(n)対O(n))。 .... 2つのテーブルで文字セットが異なる場合は例外です。 MySQLが2つの異なる文字セットにマッチしようとすると、大きな問題になります。理由を知っている人は、ちょうど遅いmmkayです。

第3に、この大幅な再設計を必要とするほどあなたのインサートは本当に遅かったですか?あなたの質問からは明らかではありませんが、無作為挿入のパフォーマンスがワークロードに大きな影響を及ぼしていて、非常に非標準的なテーブル構造を作成する必要があったため、他のすべての作業をより困難にし、その周りに?

最後に、一括挿入についての最後の質問 - あなたが行を事前作成すると、挿入は機能しません(ON DUPLICATE KEYで何かをしない限り)。しかし、私はいつもそうしようとしていない非常に良い理由がない限り、この種のIDのIDに固執しようとします。

関連する問題