私は決して DBA ではありませんが、単純なデータベースについては独学できると思っていました。ただし、このクエリには困惑しています。
私は2つのテーブルを持っています。1 つは、私の Web サイトの各ページの名前を保持します。もう 1 つは、ページがアクセスされるたびに 1 つのレコードを保持します。これら 2 つのテーブルを結合して、各ページの実行時間を平均および合計所要時間として調べ、最適化の取り組みが必要な場所を判断できるようにします。これは私のクエリです:
SELECT reqtemp.template_path, reqtemp.template_name,
round(AVG(req.request_execution_time)) AS week_avg_exec_time, COUNT(DISTINCT req.skey) AS week_count, SUM(req.request_execution_time) AS week_total_time,
round(AVG(req2.request_execution_time)) AS month_avg_exec_time, COUNT(DISTINCT req2.skey) AS month_count, SUM(req2.request_execution_time) AS month_total_time,
round(AVG(req3.request_execution_time)) AS old_avg_exec_time, COUNT(DISTINCT req3.skey) AS old_count, SUM(req3.request_execution_time) AS old_total_time
FROM log_exectime_request_tmp reqtemp
LEFT JOIN log_exectime_request req ON reqtemp.skey = req.log_exectime_req_tmp_skey
AND req.request_date >= DATE_SUB(Now(), INTERVAL 7 DAY)
LEFT JOIN log_exectime_request req2 ON reqtemp.skey = req2.log_exectime_req_tmp_skey
AND req2.request_date >= DATE_SUB(Now(), INTERVAL 30 DAY)
LEFT JOIN log_exectime_request req3 ON reqtemp.skey = req3.log_exectime_req_tmp_skey
AND req3.request_date >= DATE_SUB(Now(), INTERVAL 365 DAY)
AND req3.request_date <= DATE_SUB(Now(), INTERVAL 335 DAY)
GROUP by reqtemp.template_path, reqtemp.template_name
ORDER BY week_total_time DESC
私の理解では、これは大きなテーブルに 2000 レコードしかないミリ秒単位で実行されるはずです。少なくとも、最終的には数十万または数百万のレコードを本番環境で実行する必要があるため、期待しています。代わりに、前回試したときは 53 分かかりました。「Explain」は、log_exectime_request_tmp でテーブル スキャンを実行していることを示しています。これは、テーブルに 83 レコードしかなく、その両方の列が使用されているため問題ありません。他の 3 つの結合は、skey と request_date のインデックスを使用していますが、これも正しいようです。
誰でも最適化のアドバイスを提供できますか? なぜこのような小さなテーブルがこのような問題を引き起こすのでしょうか? クエリの構成が不十分ですか?
テーブルの DDL は次のとおりですが、ファイルを添付してデータを入力する方法が見つかりません (見逃しているのでしょうか?)。
CREATE TABLE `log_exectime_request`
(
`skey` integer (11) NOT NULL AUTO_INCREMENT ,
`log_exectime_req_tmp_skey` integer (11),
`request_date` datetime,
`request_execution_time` integer (11),
`query_execution_time` integer (11),
`template_execution_time` integer (11),
`logging_execution_time` integer (11),
PRIMARY KEY (`skey`)
) TYPE=InnoDB CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER TABLE `elegantgalleries`.`log_exectime_request` ADD INDEX `date_tempSkey` (`log_exectime_req_tmp_skey`,`request_date` );
CREATE TABLE `log_exectime_request_tmp`
(
`skey` integer (11) NOT NULL AUTO_INCREMENT ,
`template_path` varchar (500),
`template_name` varchar (250),
PRIMARY KEY (`skey`)
) TYPE=InnoDB CHARACTER SET latin1 COLLATE latin1_swedish_ci;