第一次发帖……我通常可以通过搜索找到答案,但这似乎是一个晦涩难懂的情况;
言归正传。我使用专为从父表搜索而设计的表创建了几个搜索。我遇到了这样一种情况,即我编写的查询在 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)
为什么??我已经多次重写了这个查询,我在网上阅读的所有内容似乎都指向这个查询被正确编写。有任何想法吗?提前致谢!