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');

目的は、顧客からのすべての担当者の売上を合計することです。顧客データと担当者データは関連付けられてテーブルに格納され、テーブルはテーブルに関連付けられます。invoiceinvoice lineinvoice

私が使用しているデータサイズの場合、クエリには約0.015秒かかります

id_invoicesクエリ内のを、VARCHARであるが一意のフラグが付けられていない別のPKに変更しました。

その理由は、以前は、invoiceがDBに挿入されるというひどい設計でした。その後、invoice外部キーとして使用するためにの自動インクリメントされたPKを要求するクエリがすぐに続きました。

BULK INSERTを効果的に使用するには、自動インクリメントされた「バニラ」INT PKに依存せずに、実質的にすべてのデータの一意の識別子にアクセスする必要がありました。これは、上記のように実行し、外部キーとして機能する列を追加するなどして実現しました。

私の挿入率は素晴らしいですが、クエリには7秒以上かかります

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

次の動きはintidに戻っているように見えますが、MySQLが挿入時に自動インクリメントできるようにする代わりに、これらのintインデックスを手動で作成して、一括挿入を引き続き使用できるようにします。クエリの観点からは、それは問題ではないはずです...そうすべきですか?

どんな助けでもいただければ幸いです。

デーン

4

1 に答える 1

1

まず、EXPLAIN を使用してクエリ プランで何が起こっているかを判断し、他に何が変更されているかを確認する必要があります。

第 2 に、VARCHAR 列は INT 列よりも照合が遅くなりますが、通常は一定の増加にすぎません (たとえば、k が n に関連していない場合、k*O(n) と O(n) のようになります)。....2 つのテーブルで文字セットが異なる場合は除きます。次に、MySQL が 2 つの異なる文字セットを一致させようとするため、大きな問題になります。理由は誰にもわかりませんが、単に遅いだけです。

第三に、あなたの挿入は、この大規模な再設計を必要とするほど遅かったのですか? あなたの質問からあなたが何をしているのかは明らかではありませんが、ランダム挿入のパフォーマンスがワークロードに大きな影響を与え、非常に非標準的なテーブル構造を作成する必要があったため、他のすべての作業が難しくなり、遅くなったことを理解するのは困難ですその周りに?

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

于 2012-04-24T05:25:10.037 に答える