ここ数日間、お客様の実稼働環境 (データベースは mysql 5.1) でのこのストアド プロシージャの実行時間は 30 ~ 40 分を超えているとのことです。このストアド プロシージャの実装を改善するには:
1. 2 つのテーブルのクエリ (ビジネス上のニーズにより、テーブルのサブクエリも含まれます) は、2 つのテーブルのデータにそれぞれ挿入されます。それぞれ 310W+、120W
2. 途中でさらに作業を行う必要があります。一時テーブルのデータ グループ by を別の一時テーブルに挿入します。3. 最後に、一時テーブルのデータ グループ by を挿入します。正式なテーブルに挿入したデータは 140W+
そして、ここ数日でパフォーマンスを最適化しました。私は道をどんどん遠くへ進み、あらゆる種類の方法を試し、あらゆる種類の苦労を経験しました。
アプリからの写真
さまざまな試み:
まず、この実装のロジックは少し複雑だと感じましたが、その後、私のアイデアに従って実装を簡素化しました。ただし、パフォーマンスは向上しません。なぜなら、私の実装では大量のデータが最前面に来るため、後続の操作はこの大量のデータに対してグループ化などの操作を実行する必要があるからです。したがって、私の実装は論理的に単純化されていますが、パフォーマンスは向上しません。
2 番目に、2 セットの一時テーブルが異なる論理識別子に基づいて作成されます。これにより、1 つのテーブルのデータ量がそれほど大きくならず、後続の操作への負担が軽減されます。やはり失敗に終わりました。その理由は、論理識別子の設定により、すべてが 1 つのロジック セットに基づいているため、2 番目のロジック セットは単なる形式的なものであり、実際に数百万のデータを含むテーブルをチェックするわけではないため、依然としてテーブルにプレッシャーがかかっています。 300万以上。
3. 準備されたステートメントを使用します。実際、私はステートメントの前処理のメカニズムについてはあまり知りませんが、前処理の方が効率的であると聞いただけです。おそらく同様のクエリや挿入があまりないため、パフォーマンスはまだ改善されていません。うーん、前処理の仕組みがよくわかりません。
4. サブクエリを削除し、一時テーブルを使用してデータのこの部分を保存します。この方法では、300 万を超えるデータを含むテーブルを 2 回チェックする必要があり、パフォーマンスは向上しません。
5. 一時テーブルのエンジンを myisam からメモリに変更します。データベースのグローバル変数 max_heap_table_size と tmp_table_size も、本番環境と同じ 1000M に設定されます。結果はまだ
The table 'tmp_item_bu_parter_price' is full
ログイン後にコピー
と報告されているので、データ量が多すぎてメモリがバーストしているのでしょうか?
6 番目に、ロジックのさまざまな分岐にも従ったのですが、それらはすべて同じロジックに従っていることがわかりました。これは少し欠点です。私はこれについて以前長い間考えていましたが、最初に顧客の設定を調べませんでした。
7. マルチスレッド。 insert into ...select... の構文がストアド プロシージャで使用されており、where 条件にインデックスが作成されていないため、テーブル全体のロックが発生します。マルチスレッド テストの結果は間違いなくロック テーブルであり、一部のデータの実行は失敗します。
8. 論理的には、完全に挿入されるのではなく、段階的に挿入されますが、既存のデータは引き続き更新する必要があります。したがって、パフォーマンスはほぼ同じになるはずです。
パフォーマンスは主に数百万のデータを挿入することによって消費されます。今私は完全に途方に暮れており、どう対処してよいか分かりません。
【関連する推奨事項】
1.
無料の mysql オンラインビデオチュートリアル
2.
MySQL の最新マニュアルチュートリアル
3.
以上が3 日間のパフォーマンス チューニング中に遭遇した問題の一部を共有しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。