2011-11-22 80 views
0

我遇到以下問題。我需要優化存儲超過10百萬行的表中的索引。特別耗時的查詢最多需要10秒才能加載(WHERE子句只能過濾大約2百萬行 - 必須將8百萬行分組)。我創建了一些索引(其中一些很複雜,一些更簡單),並試圖找出如何加快速度。也許我做錯了什麼。 MySQL正在使用optimized_5索引(基於EXPLAIN)。通過使用索引對GROUP BY子句的查詢進行MySQL優化

下面是表的結構和查詢:

CREATE TABLE IF NOT EXISTS `geo_reverse` (
    `fid` mediumint(8) unsigned NOT NULL, 
    `tablename` enum('table1','table2') NOT NULL default 'table1', 
    `geo_continent` varchar(2) NOT NULL, 
    `geo_country` varchar(2) NOT NULL, 
    `geo_region` varchar(8) NOT NULL, 
    `geo_city` mediumint(8) unsigned NOT NULL, 
    `type` varchar(30) NOT NULL, 

    PRIMARY KEY (`fid`,`tablename`,`geo_continent`,`geo_country`,`geo_region`,`geo_city`), 
    KEY `geo_city` (`geo_city`), 
    KEY `fid` (`fid`), 
    KEY `geo_region` (`geo_region`,`geo_city`), 
    KEY `optimized` (`tablename`,`type`,`geo_continent`,`geo_country`,`geo_region`,`geo_city`,`fid`), 
    KEY `optimized_2` (`fid`,`tablename`), 
    KEY `optimized_3` (`type`,`geo_city`), 
    KEY `optimized_4` (`geo_city`,`tablename`), 
    KEY `optimized_5` (`tablename`,`type`,`geo_city`), 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

示例查詢:

SELECT type, COUNT(*) AS objects FROM geo_reverse WHERE tablename = 'table1' AND geo_city IN (5847207,5112771,4916894,...) GROUP BY type

你有如何加速計算的任何想法?

謝謝!

+0

您是否嘗試過使用明顯的索引:在geo_reverse(tablename,geo_city)上創建索引idx1? – danihp

+0

是的。不過,MySQL選擇了optimized_5。值得注意的是,通過消除group by,查詢速度更快(6而不是8秒),但仍然太慢。 –

回答

2

我會使用下面的索引:(geo_city,tablename,type) - geo_city顯然比tablename更具選擇性,因此它應該在左邊。在應用條件之後,其餘部分應按類型進行排序以進行分組。

+0

嗨,謝謝你的提示。我只是試了一下 - 它更慢 - 超過11秒:(你有什麼其他的想法嗎? –

+0

@FlexJack,很奇怪你是否試過在桌面上運行OPTIMIZE?查詢是否使用索引? – newtover

+0

@newtover - 我強制MySQL使用該索引並使用EXPLAIN檢查其狀態 - 它使用的是filesort,我認爲這是原因。但是,我不知道爲什麼。數據量太大?我應該調整MySQL設置嗎? –