2014-05-21 116 views
1

我有如下表:優化一個簡單的MySQL查詢

idTelephone int(11) 
name varchar(255) 
nameUrl varchar(255) 
address text 
city varchar(255) 
cityUrl varchar(255) 
cellphone int(1) 

用以下指標:

PRIMARY idTelephone 
nameUrl BTREE 
cityUrl BTREE 
cityUrlNameUrl BTREE cityUrl, nameUrl 
search FULLTEXT name, nameUrl, address, city 
name FULLTEXT 

有一個在我的網站上的網頁中,我有一個展示的所有電話號碼一個分頁。 所以我用下面的查詢(頁26994):

SELECT * FROM dir_Telephone WHERE 1=1 ORDER BY nameUrl LIMIT 269930, 10 

但它真的很慢...你怎麼能優化這樣一個簡單的查詢?

用於解釋輸出是:

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 SIMPLE dir_Telephone ALL  NULL   NULL  NULL  NULL 269965 Using filesort 

沒有WHERE語句的結果是:

EXPLAIN (SELECT * FROM dir_Telephone ORDER BY nameUrl LIMIT 269930 , 10); 

id select_type  table type possible_keys key  key_len  ref  rows Extra 
1 SIMPLE dir_Telephone ALL  NULL   NULL NULL  NULL 269965 Using filesort 

CREATE語句是:

CREATE TABLE IF NOT EXISTS `dir_Telephone` (
    `idTelephone` int(11) NOT NULL, 
    `name` varchar(255) DEFAULT NULL, 
    `nameUrl` varchar(255) DEFAULT NULL, 
    `address` text, 
    `city` varchar(255) DEFAULT NULL, 
    `cityUrl` varchar(255) DEFAULT NULL, 
    `cellphone` int(1) unsigned DEFAULT NULL, 
    `htmlPublic` text, 
    `htmlComplete` text, 
    PRIMARY KEY (`idTelephone`), 
    KEY `nameUrl` (`nameUrl`), 
    KEY `cityUrl` (`cityUrl`), 
    KEY `cityUrlNameUrl` (`cityUrl`,`nameUrl`), 
    FULLTEXT KEY `search` (`name`,`nameUrl`,`address`,`city`), 
    FULLTEXT KEY `name` (`name`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+0

您可以添加'EXPLAIN'的輸出嗎? – VMai

+0

我剛剛用輸出編輯了問題 –

+0

你說你在nameUrl上有一個索引,但它沒有被使用。並且大量數據上的文件緩慢。你能發表SHOW CREATE TABLE的結果嗎?如果刪除無用​​的WHERE子句會發生什麼? – VMai

回答

3

你想要做的是什麼在表中添加一個rownumber列。一種方法是定義一個新表,就像舊錶一樣,但是具有自動遞增的列。然後將數據加載到它。或者,您可以執行以下操作。

alter table dir_Telephone add rownum integer; 

update dir_telephone cross join 
     (select @rn := 0) var 
    set rownum = (@rn := @rn + 1) 
    order by nameUrl; 

create index dir_Telephone_rownum on dir_Telephone(rownum); 

然後,當您運行查詢時,不要在limit子句中使用偏移量。使用where子句:

SELECT * 
FROM dir_Telephone 
WHERE 1=1 AND rownum >= 269930 
ORDER BY rownum 
LIMIT 10;