2011-03-13 163 views
0

我有這兩個表:MySQL查詢優化幫助

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查詢?

這裏是我的原單後:

Mysql join with time matching

回答

0

嘗試:

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 

這裏是我49年5月1日解釋輸出:

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' 
0

你是在一個比比較少加入:

c.usagetime <= j.starttime 

這意味着,具有比工作開始時間少了usagetime每個CPU記錄將被加入到工作記錄中。隨着時間的推移,這個查詢會變得越來越慢,因爲它會在幾個月前加入信息,如果它存在的話。你只對工作開始前的最新條目感興趣。

如果您確信在作業開始時間的某個時間範圍內有cpuinfo記錄,請將其更改爲範圍搜索。

c.usagetime between j.starttime and date_sub(j.starttime, interval 5 minute) 

這應該大大加快。你可以使間隔越小越好。

0

你可以試試這個小竅門:

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; 

這應該會導致服務器花一點點的IT運表cpuinfo中的一部分,也不是全部或一半。

PS:嘗試考慮間隔值,也許5分鐘在你的情況下就足夠了。