1

ユーザーのメッセージに対して部分的な単語検索を行うスクリプトを書いています。各会話にはmail_idがあり、個々のメッセージにはmsg_idがあります。

メッセージ内の各単語の行を含むテーブル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

ただし、一度に1つの単語を検索すると、各単語を完了するのに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
4

1 に答える 1

0

この場合、w1 のインデックス multi を作成します。

ALTER TABLE `mail_word_index`
ADD INDEX `multi` USING BTREE (`sender_id`, `mail_id`, `msg_id`, `word`) ;
于 2012-07-24T13:12:27.003 に答える