1

私は自分自身に答えることができるはずですが、私は答えることができず、またグーグルで答えを見つけることができないという1つの質問:

この構造の500万行を含むテーブルがあります。

CREATE TABLE IF NOT EXISTS `files_history2` (
  `FILES_ID` int(10) unsigned DEFAULT NULL,
  `DATE_FROM` date DEFAULT NULL,
  `DATE_TO` date DEFAULT NULL,
  `CAMPAIGN_ID` int(10) unsigned DEFAULT NULL,
  `CAMPAIGN_STATUS_ID` int(10) unsigned DEFAULT NULL,
  `ON_HOLD` decimal(1,0) DEFAULT NULL,
  `DIVISION_ID` int(11) DEFAULT NULL,
  KEY `DATE_FROM` (`DATE_FROM`),
  KEY `FILES_ID` (`FILES_ID`),
  KEY `CAMPAIGN_ID` (`CAMPAIGN_ID`),
  KEY `CAMP_DATE` (`CAMPAIGN_ID`,`DATE_FROM`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

実行すると

SELECT files_id, min( date_from )
FROM files_history2
WHERE campaign_id IS NOT NULL
GROUP BY files_id

クエリはステータス「データの送信中」で8時間以上停止します(その後、プロセスを強制終了しました)。

ここで説明します:

id  select_type     table           type    possible_keys           key     key_len     ref     rows        Extra
1   SIMPLE          files_history2  ALL     CAMPAIGN_ID,CAMP_DATE   NULL    NULL        NULL    5073254     Using where; Using temporary; Using filesort

必要なキーを生成したと思いますが、クエリにはそれだけの時間がかかるはずですよね?

4

3 に答える 3

5

別のインデックスを提案します...(Files_ID、Date_From、Campaign_ID)のインデックス...

group byはFiles_IDにあるため、これらをグループ化する必要があります。次に、MIN(Date_From)、つまり2番目の位置になります...次に、最終的にCampaign_IDがnullではない資格を得ることになります。その理由は...

すべてのキャンペーンIDを最初に配置すると、すべてのNULLが邪魔になりません...これで、1,000のキャンペーンがあり、Files_IDは多くのキャンペーンにまたがっており、それらも多くの日付にまたがっています。

私が予測しているインデックスによって、最初にFiles_IDによって、各「files_id」がグループと一致するようにすでに順序付けられています。次に、その中で、すべての最も早い日付がインデックス付きリストの一番上にあります...素晴らしい、ほぼそこに、そしてキャンペーンIDで。そこにある可能性のあるNULLをスキップして、次のFiles_IDに進みます。

これが理にかなっていることを願っています-NULL値のキャンペーンを持つエントリがたくさんない限り。

また、インデックスの3つの部分すべてをクエリの条件と出力列に一致させることで、データの生データファイルに戻る必要がなくなり、すべてをインデックスから直接取得します。

于 2012-11-15T00:24:21.623 に答える
1

カバーインデックス(CAMPAIGN_ID、files_id、date_from)を作成し、そのパフォーマンスを確認します。あなたの問題は、グループ化されていないことと、date_fromが同じインデックスを使用できないことが原因であると思われます。

CREATE INDEX your_index_name ON files_history2 (CAMPAIGN_ID, files_id, date_from);

これが機能する場合CAMPAIGN_IDは、複合インデックスに含まれているポイントインデックスを削除できます。

于 2012-11-14T21:53:29.383 に答える
1

集計(関数MIN)とグループ化のため、クエリは遅くなります。解決策の1つは、集約サブクエリをWHERE句からFROM句に移動することでクエリを変更することです。これは、使用しているアプローチよりもはるかに高速です。

次のことを試してください:

SELECT f.files_id 
FROM file_history2 AS f 
JOIN ( 
SELECT campaign_id, MIN(date_from) AS datefrom 
FROM file_history2 
GROUP BY files_id 
) AS f1 ON f.campaign_id = f1.campaign_id AND f.date_from = f1.datefrom; 

一時テーブルが機能しない場合は、これを選択するだけでパフォーマンスが大幅に向上するはずです。

于 2012-11-14T22:11:30.303 に答える