current_vacature_responseに88kレコードが含まれており、daily_vacature_responseに10kレコードが含まれている場合、次のクエリの実行に約30秒かかります。 EXPLAINの使用私は、current_vacature_response
テーブルから使用されたインデックスがないと結論付けました。私は基本的なインデックスをいくつか追加しましたが、どれも使用されていないようです。このクエリを高速化するためには、どのようなインデックスを設定する必要がありますか?このMYSQL JOIN/GROUP BY/HAVINGクエリを高速化するために、どのインデックスを追加する必要がありますか?
問合せ:
SELECT c.`stats_date` as `stats_date`
FROM `current_vacature_response` c
LEFT JOIN `daily_vacature_response` d ON (c.`stats_date` = d.`stats_date`)
GROUP BY c.`stats_date`, d.`stats_date`
HAVING max(d.`last_stats_datetime`) IS NULL
OR MAX(d.`last_stats_datetime`) < MAX(c.`created_datetime`);
current_vacature_responseテーブル定義:
CREATE TABLE `current_vacature_response` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_datetime` datetime NOT NULL,
`site_id` tinyint(1) unsigned NOT NULL,
`stats_date` date NOT NULL,
`type` enum('typ1', 'type2') NOT NULL,
`vacature` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `current_vacature_created_datetime` (`created_datetime`),
KEY `current_vacature_response_vacature` (`vacature`),
KEY `current_vacature_response_type` (`type`),
KEY `current_vacature_stats_date` (`stats_date`)
) ENGINE=MyISAM AUTO_INCREMENT=88210 DEFAULT CHARSET=utf8;
daily_vacature_responseテーブル定義:
CREATE TABLE `daily_vacature_response` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`contact` int(10) unsigned NOT NULL DEFAULT '0',
`site_id` tinyint(1) unsigned NOT NULL,
`spotlight_result` int(10) unsigned NOT NULL DEFAULT '0',
`stats_date` date NOT NULL,
`last_stats_datetime` datetime NOT NULL,
`vacature` int(10) unsigned NOT NULL,
`created_datetime` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `daily_vacature_response_key` (`site_id`,`vacature`,`stats_date`),
KEY `daily_vacature_response_last_stats_datetime` (`last_stats_datetime`),
KEY `daily_vacature_response_stats_date` (`stats_date`)
) ENGINE=MyISAM AUTO_INCREMENT=9802 DEFAULT CHARSET=utf8;
は説明出力:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: c
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 88209
Extra: Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: d
type: ref
possible_keys: daily_vacature_response_stats_date
key: daily_vacature_response_stats_date
key_len: 3
ref: reporting_development.c.stats_date
rows: 99
Extra:
あなたは他のすべての操作の後に実行される句を、HAVINGにのみフィルタリングしているので、それはあまりにもです索引を使用するのが遅れます。フィルタリングが早い段階(where句または結合条件)で実行されるようにクエリを書き換えることが最善の方法です。そうしないと、MySQLは常にcurrent_vacature_responseテーブル全体をスキャンする必要があります。だから唯一の解決策は、クエリを書き換えることですが、それを確実に行うために、stats_date、created_datetime、last_stats_datetimeについて説明してください。あなたはまた、いくつかの入力例と期待される出力を提供できますか? –
TNX、私はそれをはるかに高速クエリ(4MS)を書き換えました:c.'stats_date' BY current_cv_response'のC \t GROUP 'FROM c.'stats_date' \tを選択 \t MAX(c.'created_datetime'を)持っていません \t IN(d.'stats_date' BY daily_cv_response' D \t \t d.'stats_date' = c.'stats_date' \t \t GROUP 'FROM MAX(d.'last_stats_datetime') \t \tを選択します)。 –