2012-05-16 74 views
1

我正在編寫一個腳本來對用戶的消息進行部分詞搜索。每個會話都有一個mail_id,每個消息都有一個msg_id。MySQL:通過連接多次搜索同一個表

我有一個表mail_word_index,它包含消息中每個單詞的一行。

CREATE TABLE IF NOT EXISTS `mail_word_index` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `sender_id` int(10) unsigned NOT NULL DEFAULT '0', 
    `dest_id` int(10) unsigned NOT NULL DEFAULT '0', 
    `mail_id` int(10) unsigned NOT NULL DEFAULT '0', 
    `msg_id` int(10) unsigned NOT NULL DEFAULT '0', 
    `word` varchar(15) NOT NULL DEFAULT '', 
    PRIMARY KEY (`id`), 
    KEY `dest_id` (`dest_id`,`word`), 
    KEY `sender_id` (`sender_id`,`word`), 
    KEY `multiple_words` (`mail_id`,`msg_id`,`word`) 
) ENGINE=MyISAM ; 

我有一個查詢這需要0.01秒至完成

SELECT DISTINCT w1.mail_id FROM mail_word_index AS w1, 
mail_word_index AS w2 
WHERE w1.sender_id=1 
AND w1.word LIKE 'str%' 
AND w1.mail_id=w2.mail_id 
AND w1.msg_id=w2.msg_id 
AND w2.word LIKE 'con%' LIMIT 20 

然而,在時間搜索一個字只需要0.002秒完成每一個,和0.004秒總:

SELECT DISTINCT w1.mail_id FROM mail_word_index AS w1 
WHERE w1.sender_id=1 AND w1.word LIKE 'str%' LIMIT 20 

SELECT DISTINCT w1.mail_id FROM mail_word_index AS w1 
WHERE w1.sender_id=1 AND w1.word LIKE 'con%' LIMIT 20 

內部連接似乎減慢了第一個查詢。如何更改第一個查詢以使其更快?

的EXPLAIN告訴我:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE w1 range sender_id,multiple_words sender_id 21 NULL 1 Using where; Using temporary 
1 SIMPLE w2 ref multiple_words multiple_words 8 game-node4.w1.mail_id,game-node4.w1.msg_id 8 Using where; Using index; Distinct 
+3

你* *嚴重擔憂** **爲6ms? – eggyal

+0

Afaik,您的'multiple_words'已經是該查詢的最佳可能索引。由於MySQL必須加入,因此速度會變慢。 – Konerak

+0

隨着表越來越大,同時搜索更多單詞,查詢與多個連接之間的時間差以及每個單獨查詢的總時間變得更大 – ZPS

回答

0

在這種情況下創建W1指數多:

ALTER TABLE `mail_word_index` 
ADD INDEX `multi` USING BTREE (`sender_id`, `mail_id`, `msg_id`, `word`) ;