2010-09-03 70 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

相關問題