2010-09-03 74 views
3

以下查询使用临时文件和filesort。如果可能,我想避免这种情况。有没有更好的索引来加速这个查询?

SELECT lib_name, description, count(seq_id), floor(avg(size)) 
FROM libraries l JOIN sequence s ON (l.lib_id=s.lib_id) 
WHERE s.is_contig=0 and foreign_seqs=0 GROUP BY lib_name; 

EXPLAIN说:

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra 
1,SIMPLE,s,ref,libseq,contigs,contigs,4,const,28447,Using temporary; Using filesort 
1,SIMPLE,l,eq_ref,PRIMARY,PRIMARY,4,s.lib_id,1,Using where 

的表是这样的:

CREATE TABLE `libraries` (
    `lib_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `lib_name` varchar(30) NOT NULL, 
    `method_id` int(10) unsigned DEFAULT NULL, 
    `lib_efficiency` decimal(4,2) unsigned DEFAULT NULL, 
    `insert_avg` decimal(5,2) DEFAULT NULL, 
    `insert_high` decimal(5,2) DEFAULT NULL, 
    `insert_low` decimal(5,2) DEFAULT NULL, 
    `amtvector` decimal(4,2) unsigned DEFAULT NULL, 
    `description` text, 
    `foreign_seqs` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1 means the sequences in this library are not ours', 
    PRIMARY KEY (`lib_id`), 
    UNIQUE KEY `lib_name` (`lib_name`) 
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1; 

序列

CREATE TABLE `sequence` (
    `seq_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `seq_name` varchar(40) NOT NULL DEFAULT '', 
    `lib_id` int(10) unsigned DEFAULT NULL, 
    `size` int(10) unsigned DEFAULT NULL, 
    `add_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `sequencing_date` date DEFAULT '0000-00-00', 
    `comment` text DEFAULT NULL, 
    `is_contig` int(10) unsigned NOT NULL DEFAULT '0', 
    `fasta_seq` longtext, 
    `primer` varchar(15) DEFAULT NULL, 
    `gc_count` int(10) DEFAULT NULL, 
    PRIMARY KEY (`seq_id`), 
    UNIQUE KEY `seq_name` (`seq_name`), 
    UNIQUE KEY `libseq` (`lib_id`,`seq_id`), 
    KEY `primer` (`primer`), 
    KEY `sgitnoc` (`seq_name`,`is_contig`), 
    KEY `contigs` (`is_contig`,`seq_name`) USING BTREE, 
    CONSTRAINT `FK_sequence_1` FOREIGN KEY (`lib_id`) REFERENCES `libraries` (`lib_id`) 
) ENGINE=InnoDB AUTO_INCREMENT=61508 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC; 

我能做些什么来改变查询速度吗?如果不是,那么当(对于Web应用程序)将上述查询的结果放入MEMORY表中时值得吗?

回答

1

第一种策略:让mySQL更快地找到您想要汇总的记录。

你已经有了一个关于sequence.is_contig的索引。您可以尝试对libraries.foreign_seqs建立索引。我不知道这是否会有所帮助,但值得一试。

第二种策略:看看你能否让你的排序在内存中运行,而不是在文件中运行。尝试使sort_buffer_size参数变大。这将消耗服务器上的RAM,但这是RAM的用途。

第三个策略:如果您的应用程序需要做很多查询,但只是稍微更新底层数据,请自行提出建议并创建一个汇总表。也许使用EVENT重新制作汇总表,然后每隔几分钟运行一次。如果你要遵循这个策略,首先创建一个视图,并让你的应用从视图中获取信息。然后得到总结表的东西工作,放下视图,并提供摘要表与视图相同的名称。这样你的数据模型就可以工作,你的应用程序设计工作可以独立进行。

最终建议:如果这是真正缓慢变化的汇总数据,请切换到myISAM。这种数据争夺的速度要快一些。

+0

感谢您提供非常明确和完整的答案。在这种情况下,Reindexing不起作用。 sort_buffer_size = 2M,我认为它在正常的高端 - 或者至少这是我的阅读建议。所以我打算用一个汇总表。 – dnagirl 2010-09-08 13:25:44

相关问题