2010-11-01 82 views
1

Here`s我SHOW CREATE TABLE TBL:優化MySQL查詢(按組和秩序 - >使用索引;使用臨時;使用文件排序)

CREATE TABLE IF NOT EXISTS `msc_pagestats` (
    `id` int(10) unsigned NOT NULL auto_increment, 
    `domain` varchar(250) NOT NULL, 
    `file` varchar(200) NOT NULL, 
    `simbol` varchar(100) NOT NULL, 
    `request_time` timestamp NULL default CURRENT_TIMESTAMP, 
    `querystring` mediumtext NOT NULL, 
    `host` varchar(100) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `myindex` (`simbol`,`request_time`,`file`,`domain`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=248008 ; 

所以基本上這個表跟蹤什麼simbols一直最根據查詢字符串,在網站中搜索最多,最受歡迎,最受歡迎的內容。

我的查詢是:

SELECT `simbol`, count(*) AS requests 
FROM msc_pagestats 
WHERE 1=1 AND request_time > '20100504000000' 
     AND simbol NOT LIKE '' 
GROUP BY `simbol` 
     ORDER BY requests DESC 
LIMIT 0, 15; 

這個查詢解釋說:

id select_type table type possible_keys key key_len ref rows Extra 

1 SIMPLE msc_pagestats index NULL myindex 561 NULL 24961 Using where; Using index; Using temporary; Using filesort 

所以查詢tryes以獲得最新的小時當今最accesed符號。

這是我已經試過爲了做擺脫使用臨時使用文件排序的:

  1. 添加一個ID作爲主鍵,使用COUNT(id) AS requests代替COUNT(*) AS requests;
  2. 卸下where 1=1simbol not like='' ,雖然沒有證明有很大的區別,
  3. 添加一個多索引而不是reqular索引,以前有每列ex(KEY(request_time),KEY(file),KEY(domain),KEY(simbol))上的索引。

我對優化並不擅長,所以我沒有選擇好。

這裏是我的 'mysq_slow_query' 文件的轉儲:

Query_time:3 Lock_time:0 Rows_sent:15 Rows_examined:220297

use kmarket; 
SELECT `simbol`, count(*) AS requests 
FROM msc_pagestats 
WHERE 1=1 AND request_time > '20100504000000' 
     AND simbol NOT LIKE '' 
     GROUP BY `simbol` 
ORDER BY requests DESC 
LIMIT 0, 15; 

任何幫助,將不勝感激,謝謝:)

回答

1

在向運行時計算的字段添加索引時沒有太多意義,它仍然需要在每次運行時進行排序/索引。

(request_time,simbol)上的索引可能允許優化器更快速地排除很多行,並且還會縮短密鑰長度。

+0

非常感謝您的幫助。雖然它沒有消除使用臨時ori文件,但現在它快了50%。我將嘗試在未來看到如何實現一個表格結構以最好地滿足我的需求。祝你有個美好的一週。 – Gabriel 2010-11-02 10:20:46

+0

如果您需要使用該性質的計數,最好將計數緩存在表格上 - 這樣您就可以對其進行索引,並且它將快速實現。 – Oddman 2016-10-27 04:41:27