2

以下のクエリを実行するのに 3 時間 50 分 39.70 秒かかるのは、許容範囲ですか、それとも正常ですか?

CREATE TABLE ukbm001marketing.CampaignHistory_v2
                (
                AddressId int,                          
                CampaignId int,                         
                CampaignTypeId int,                      
                OpenUserId nvarchar(255),
                OpenDate datetime,
                CloseUserId nvarchar(255),
                CloseDate datetime
                );

INSERT INTO ukbm001marketing.CampaignHistory_v2

SELECT a.ContactId,
       b.CampaignCodeId,
       c.CampaignId,
       'mballinger',
       now(),
       NULL,
       NULL -- SELECT *
FROM 
    ukbm001marketing.temp_ContactHistory_grtthn2009_raw a
LEFT JOIN 
    ukbm001marketing.temp_CampaignCode_raw b ON a.CampaignCode = b.CampaignCode
                                             AND a.ContactDate = b.ContactDate
                                             AND a.Load_Date = b.Load_Date
LEFT JOIN 
    ukbm001marketing.temp_ContactCodes_raw c ON a.ContactCode = c.ContactCode;

クエリで使用されるテーブル:

  • ukbm001marketing.temp_ContactHistory_grtthn2009_raw565,832行あります
  • ukbm001marketing.temp_CampaignCode_raw9505行あります
  • ukbm001marketing.temp_ContactCodes_raw39行あります

このクエリをコマンド プロンプト ラインで実行しました。

過去に、私は Microsoft SQL Server (IS 部門によって設定されたもの) を使用していました。私は自分のプロジェクトに取り組んでおり、次のように設定しています。

EasyPHP12.1 を使用してインストール

  • アパッチ/2.4.2 (Win32) PHP/5.4.6
  • ソフトウェア バージョン: 5.5.27-log - MySQL Community Server (GPL)

ラップトップの仕様

  • プロセッサー: Intel(R) Core(TM) i7-2620M CPU @ 2.70ghz 2.70ghz
  • RAM: 8.00 GB (7.88 GB 使用可能)
  • システム 64 ビット Windows システム

システムは 50% の CPU 使用率で実行されていました。

どのテーブルにもインデックスを作成していません。テーブルに主キーを与えていません。この問題はシステム パフォーマンスに関連していますか? データベースの設計上の問題ですか?それともmysqlサーバーの設定ですか?

ご協力いただきありがとうございます。

4

1 に答える 1

1

これは間違いなくインデックスの問題です。インデックスを使用せずに、3 つのフィールドの 565.832 行カウント テーブルを 9505 テーブルに結合しています。これにより、両方のテーブルで完全なテーブルスキャンが行われます。つまり、サーバーは実際にこれらの 565832 をすべてディスクから取得し (-> slooow)、メモリ内で一致させる必要があります。

あなたが提供した限られた情報を考えると、MySQL の最適化を行っていないと思います。つまり、join_buffer_size がかなり小さくなるということです。これにより、MySQL がすべてをバッファに格納することができないため、さらに多くのテーブル スキャンが発生します。そのため、MySQL に実際に使用するように指示しない場合、8Gb の RAM は何の役にも立ちません。

したがって、基本的には、'a' および 'b' テーブルの両方で、campaigncode、contactdate、および load_date フィールドに複数列のインデックスを作成し、'a' および 'c' テーブルの contactcode フィールドにインデックスを追加します。

テーブルの構造によっては (b または c テーブルにここに記載されていない他のフィールドが多数含まれている場合は間違いありません)、「b」テーブルのインデックスに Campaigncodeid フィールドを追加し、 「c」テーブル。このようにして、MySQL はインデックスを使用してすべてのデータを取得できるようになり、2 つのフィールドを取得するために実際のデータ テーブルにアクセスする必要がなくなります。明らかに、ペナルティはインデックスが大きくなることです。MySQL のチューニングと組み合わせることで、インデックスをメモリに保持し、全体をさらに高速化できます。

于 2013-05-01T11:21:26.520 に答える