慢MySQL查询不使用filesort

时间:2010-05-03 23:24:34

标签: mysql performance

我的主页上的查询越来越慢,因为我的数据库表越来越大。

tablename = tweets_cache 行= 572,327

这是我目前正在使用的查询,速度很慢,超过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,provice和发布都有索引?执行查询的配置文件显示它没有使用索引对查询进行排序,并且正在使用非常慢的filesort。

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

我尝试使用“profiles& mp”添加新的multie-colum索引。解释显示这个新索引列在“possible_keys”和“key”下,但查询时间不变,仍然超过5秒。

以下是查询中的screenshot个探查器信息。

奇怪的是,我在我的本地桌面上进行了数据库转储以便进行测试,所以我不会搞砸实时网站。我本地的相同查询运行超快,毫秒。所以我将所有相同的mysql启动变量从服务器复制到我的本地,以确保没有可能导致这种情况的设置。但即便如此,本地查询运行速度超快,但实时服务器上的查询超过5秒。

我的数据库服务器仅使用了大约800MB的4GB可用空间。 这是我正在使用的相关my.ini设置

default-storage-engine = 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
#尝试使用thread_concurrency的CPU数量* 2 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'

2 个答案:

答案 0 :(得分:6)

  

我不确定为什么它不使用索引,因为mp,provice和publish都有索引?

MySQL只会在表中使用一个索引。如果要在同一步骤中执行WHERE和ORDER BY,请创建一个复合索引,其中包含左侧的匹配条件和右侧的排序条件,例如。在这种情况下(province, mp, published)

关于ORDER BY optimisation

答案 1 :(得分: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;