[英]Mysql Query optimization help
我有這兩個表:
CREATE TABLE `cpuinfo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`usagetime` datetime DEFAULT NULL,
`cpuusage` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `idx_usagetime` (`usagetime`),
KEY `idx_usage` (`cpuusage`));
CREATE TABLE `jobinfo` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`starttime` datetime NOT NULL,
`endtime` datetime DEFAULT NULL,
`jobname` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `idx-startime` (`starttime`),
KEY `idx-endtime` (`endtime`));
使用此查詢:
explain SELECT j.id, j.starttime, j.endtime, j.jobname, c.cpuusage
FROM (SELECT j.id, j.starttime, j.endtime, j.jobname, MAX(c.usagetime) AS usagetime
FROM jobinfo AS j
LEFT JOIN cpuinfo AS c ON c.usagetime <= j.starttime
GROUP BY j.id) AS j
JOIN cpuinfo AS c ON j.usagetime = c.usagetime
ORDER BY j.starttime
運行大約需要10分鍾。
對於解釋命令,我得到了這個輸出
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
---------------------------------------------------------------------------
1,PRIMARY,<derived2>,ALL,NULL,NULL,NULL,NULL,4557,"Using filesort"
1,PRIMARY,c,ref,idx_usagetime,idx_usagetime,9,j.usagetime,1,"Using where"
2,DERIVED,j,ALL,NULL,NULL,NULL,NULL,4557,"Using temporary; Using filesort"
2,DERIVED,c,index,idx_usagetime,idx_usagetime,9,NULL,2880,"Using index"
您能給我一些技巧來優化此SQL查詢嗎?
這是我的原始帖子:
您正在加入小於比較:
c.usagetime <= j.starttime
這意味着使用時間少於作業開始時間的每個cpu記錄都將被加入到作業記錄中。 隨着時間的流逝,此查詢將變得越來越慢,因為它將加入幾個月前的信息(如果存在的話)。 您只對作業開始之前的最新條目感興趣。
如果確定在作業開始時間的一定時間內存在cpuinfo記錄,則將其更改為范圍搜索。
c.usagetime between j.starttime and date_sub(j.starttime, interval 5 minute)
那應該大大加快速度。 越小,間隔越好。
您可以嘗試以下小技巧:
SELECT j.id, j.starttime, j.endtime, j.jobname, c.cpuusage
FROM
(
SELECT j.id, j.starttime, j.endtime, j.jobname, MAX(c.usagetime) AS usagetime
FROM jobinfo AS j
LEFT JOIN cpuinfo AS c
ON c.usagetime <= j.starttime
WHERE c.usagetime > DATE_ADD(j.starttime, INTERVAL -1 DAY);
GROUP BY j.id
) AS j
JOIN cpuinfo AS c
ON j.usagetime = c.usagetime
ORDER BY j.starttime;
這將導致服務器僅使用cpuinfo表的一部分,而不是整個表的一半。
PS:嘗試考慮間隔值,在您的情況下,也許5分鍾就足夠了。
嘗試:
SELECT ji.starttime,
ji.endtime,
ji.jobname,
(SELECT ci.cpuusage
FROM CPUINFO ci
WHERE ci.usagetime <= ji.endtime
ORDER BY ci.usagetime DESC
LIMIT 1) AS cpuusage
FROM JOBINFO ji
這是我的5.1.49上的EXPLAIN輸出:
id select_type table type possible_keys key key_len ref rows Extra
------------------------------------------------------------------------------------------------
'1', 'PRIMARY', 'ji', 'ALL', NULL, NULL, NULL, NULL, '12', ''
'2', 'DEPENDENT SUBQUERY', 'ci', 'ALL', 'idx_usagetime', NULL, NULL, NULL, '6', 'Using where; Using filesort'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.