2010-05-03 68 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