2010-05-03 69 views
4

我的主頁上有一個查詢越來越慢,因爲我的數據庫表越來越大。緩慢MySQL查詢不使用filesort

的tablename = tweets_cache 行= 572327

這是目前我使用的是緩慢的,超過5秒查詢。

SELECT * FROM tweets_cache t WHERE t.province='' AND t.mp='0' ORDER BY t.published DESC LIMIT 50; 

如果我取出WHERE或ORDER BY,那麼查詢超快0.016秒。

我在tweets_cache表上有以下索引。

PRIMARY 
published 
mp 
category 
province 
author 

所以我不知道爲什麼它不使用索引,因爲MP,並鄧賢蘭出版的所有有指標?做一個查詢配置文件顯示它不使用索引來排序查詢,並使用真正慢的文件。

possible_keys = mp,province 
Extra = Using where; Using filesort 

我嘗試添加一個新的multie-科拉姆指數與 「型材& MP」。解釋顯示,這個新索引列在「possible_keys」和「key」下,但查詢時間不變,仍然超過5秒。

這是查詢中的分析器信息的screenshot

一些奇怪的事情,我做了我的數據庫轉儲測試我的本地桌面上,所以我不搞砸活的網站。在我的本地運行相同的查詢超快,毫秒。所以我將所有相同的mysql啓動變量從服務器複製到我的本地,以確保沒有可能導致此問題的某些設置。但即使在這之後本地查詢運行速度非常快,但活動服務器上的查詢超過5秒。

我的數據庫服務器只能使用大約800MB的4GB空間。 這裏是相關的我的。INI設置我使用

默認存儲引擎= MYISAM
MAX_CONNECTIONS = 800
跳過鎖定
的key_buffer = 512M
max_allowed_pa​​cket的= 1M
的table_cache = 512
sort_buffer_size的值= 4M
read_buffer_size = 4M
read_rnd_buffer_size = 16M
myisam_sort_buffer_size = 64M
thread_cache_size = 8默認情況下
query_cache_size變量= 128M
#嘗試號碼CPU的* 2 thread_concurrency
thread_concurrency = 8
#禁止聯邦跳聯合

的key_buffer = 512M
sort_buffer_size的值= 256M
的read_buffer = 2M
write_buffer = 2M

的key_buffer = 512M
sort_buffer_size的值= 256M
的read_buffer = 2M
write_buffer = 2M

的MySQL 5.0.67

CREATE TABLE `tweets_cache` (                
      `id` bigint(11) unsigned NOT NULL default '0',           
      `published` int(11) NOT NULL default '0',            
      `title` varchar(140) NOT NULL,               
      `category` varchar(50) NOT NULL,               
      `type` varchar(30) NOT NULL,                
      `author` varchar(25) NOT NULL,               
      `author_full` varchar(150) NOT NULL,              
      `hash` varchar(50) NOT NULL,                
      `lastupdate` int(11) NOT NULL default '0',            
      `avatar` varchar(120) NOT NULL,               
      `mp` int(1) NOT NULL default '0',              
      `followers` int(10) NOT NULL default '0',            
      `province` varchar(2) NOT NULL,               
      `talkback` varchar(15) NOT NULL default '',            
      `in_reply_to_status_id` bigint(11) unsigned NOT NULL default '0',      
      `author_id` int(11) NOT NULL default '0',            
      `tracked` tinyint(1) NOT NULL default '0',            
      `geo` varchar(25) NOT NULL default '',             
      PRIMARY KEY (`id`),                  
      KEY `published` (`published`),               
      KEY `mp` (`mp`),                   
      KEY `category` (`category`),                
      KEY `province` (`province`),                
      KEY `author` USING BTREE (`author`),              
      KEY `home` (`province`,`mp`,`published`)             
     ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='InnoDB free: 275456 kB' 
+0

什麼版本的MySQL您使用。請在此處放置「show create table」定義... – Zak 2010-05-03 23:31:37

回答

6

我不知道爲什麼它不使用索引,因爲MP,並鄧賢蘭出版的所有有指標?

MySQL只會在整個表中使用一個索引。如果您想在同一步驟中執行WHERE和ORDER BY,請在右側創建一個包含左側匹配條件的複合索引,例如,右側的排序條件。在這種情況下,(province, mp, published)

ORDER BY optimisation

+0

OMG謝謝您,我將「已發佈」添加到多列索引,現在查詢需要0.015秒! 因此,對於「mp,provice」等單列的所有索引都是無用的,因爲在我的查詢中總是有一個ORDER BY? – Canadaka 2010-05-04 00:11:13

+1

他們不*完全*無用;如果'mp'不存在,那麼基於'mp'的order-by查詢會更慢!但是,是的,擁有大量的單列索引往往不會像你想象的那樣有所幫助。 – bobince 2010-05-04 00:42:06

+0

因爲我總是通過發佈訂單,所以將所有索引轉換爲多列索引會更好。例如,將「mp」變成「mp,公佈」 – Canadaka 2010-05-04 04:39:47

0

嘗試拆分兩件查詢,這樣既可以索引工作,是這樣的:

CREATE TEMPORARY TABLE cache 
SELECT -describefields- FROM tweets_cache t WHERE t.province='' AND t.mp='0'; 

SELECT * FROM cache c ORDER BY c.published DESC LIMIT 50; 
+0

臨時表不能在MySQL中使用(並使用)索引。 – newtover 2010-05-04 11:15:55