在WHERE子句中使用OR的MySQL全文不使用索引

时间:2012-08-20 15:42:20

标签: mysql indexing where full-text-search explain

第一次发帖...我通常可以通过搜索找到答案,但这似乎是一个模糊的情况;

关于这一点。我使用专为从父表中搜索而设计的表创建了几个搜索。我遇到过一种情况,我写的查询在WHERE子句中使用OR时不会使用PRIMARY KEY索引,但如果交换了AND,它将按预期运行。这是表。

CREATE TABLE `tag_idx` (
  `tag_id` bigint(20) NOT NULL DEFAULT '0',
  `animation_id` int(10) NOT NULL DEFAULT '0',
  `tag_text` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`animation_id`,`tag_id`),
  KEY `animation_id` (`animation_id`),
  FULLTEXT KEY `tag_text` (`tag_text`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

CREATE TABLE `animation_notag_idx` (
  `animation_id` int(10) NOT NULL DEFAULT '0',
  `animation_user_id` int(10) NOT NULL,
  `contest_score` int(11) DEFAULT NULL,
  `animation_views` int(11) DEFAULT NULL,
  `animation_votes` int(255) DEFAULT NULL,
  `animation_finished` int(50) DEFAULT NULL,
  `animation_title` varchar(50) DEFAULT NULL,
  `artist_nickname` varchar(16) DEFAULT NULL,
  PRIMARY KEY (`animation_id`),
  KEY `animation_id` (`animation_id`),
  FULLTEXT KEY `animation_title` (`animation_title`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

查询;注意animation_title和tag_text在查询中的显示方式不同。

SELECT
a.animation_id,
t.tag_id,
a.contest_score,
a.animation_views,
a.animation_votes,
a.animation_finished,
a.animation_title,
a.artist_nickname,
t.tag_text,
match(a.animation_title) AGAINST ('+*funny*') as title_score,
(
SELECT MAX(
MATCH(animation_title) AGAINST('+*funny*')
 ) FROM animation_notag_idx WHERE MATCH(animation_title) AGAINST('+*funny*')
) as max_name_relevance,
match(t.tag_text) AGAINST ('+*funny*') as meta_score,
(
SELECT MAX(
MATCH(tag_text) AGAINST('+*funny*')
) FROM tag_idx WHERE MATCH(tag_text) AGAINST('+*funny*')
) as max_meta_relevance

FROM
animation_notag_idx AS a

LEFT JOIN

tag_idx AS t

on 

t.animation_id = a.animation_id
WHERE

match(a.animation_title) AGAINST ('+%funny%' IN BOOLEAN MODE)

OR

match(t.tag_text) AGAINST ('+%funny%' IN BOOLEAN MODE)


ORDER BY ((title_score / max_name_relevance) * 0.5) + ((title_score / max_meta_relevance) * 0.2) DESC

LIMIT 5
OFFSET 0;

解释......

*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: a
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3226035
        Extra: Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: PRIMARY
        table: t
         type: ref
possible_keys: PRIMARY,animation_id
          key: animation_id
      key_len: 4
          ref: text_index.a.animation_id
         rows: 1
        Extra: Using where
*************************** 3. row ***************************
           id: 3
  select_type: SUBQUERY
        table: tag_idx
         type: fulltext
possible_keys: tag_text
          key: tag_text
      key_len: 0
          ref: 
         rows: 1
        Extra: Using where
*************************** 4. row ***************************
           id: 2
  select_type: SUBQUERY
        table: animation_notag_idx
         type: fulltext
possible_keys: animation_title
          key: animation_title
      key_len: 0
          ref: 
         rows: 1
        Extra: Using where
4 rows in set (0.00 sec)


And if I swap out for the AND...

*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: a
         type: fulltext
possible_keys: animation_title
          key: animation_title
      key_len: 0
          ref: 
         rows: 1
        Extra: Using where; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: PRIMARY
        table: t
         type: ref
possible_keys: PRIMARY,animation_id
          key: animation_id
      key_len: 4
          ref: text_index.a.animation_id
         rows: 1
        Extra: Using where
*************************** 3. row ***************************
           id: 3
  select_type: SUBQUERY
        table: tag_idx
         type: fulltext
possible_keys: tag_text
          key: tag_text
      key_len: 0
          ref: 
         rows: 1
        Extra: Using where
*************************** 4. row ***************************
           id: 2
  select_type: SUBQUERY
        table: animation_notag_idx
         type: fulltext
possible_keys: animation_title
          key: animation_title
      key_len: 0
          ref: 
         rows: 1
        Extra: Using where
4 rows in set (0.00 sec)

为什么?我已经多次重写这个查询,我在网上阅读的所有内容似乎都指向这个查询正确写入。有任何想法吗?提前谢谢!

0 个答案:

没有答案