我有以下查询:
SELECT *
FROM table
WHERE
structural_type=1
AND parent_id='167F2-F'
AND points_to_id=''
# AND match(search) against ('donotmatch124213123123')
该搜索大约需要10毫秒才能运行,并在复合索引(structural_type,parent_id,points_to_id)上运行。但是,当我添加fts索引时,无论匹配条件中包含什么内容,查询都会迅速增加〜1s。基本上,每当我应用fts搜索时,它似乎都“跳过了索引”。
优化此查询的最佳方法是什么?
更新:一些解释:
EXPLAIN SELECT... # without fts
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE table NULL ref structural_type structural_type 209 const,const,const 2 100.00 NULL
带英尺(也加'力指数'):
explain SELECT ... force INDEX (structural_type) AND match...
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE table NULL fulltext structural_type,search search 0 const 1 5.00 Using where; Ft_hints: sorted
我能想到的唯一令人难以置信的东西是在fts上添加一个附加术语,以便它在其中进行过滤。例如:
fts_term = fts_term += " StructuralType1ParentID167F2FPointsToID"
like
在没有全文逻辑的情况下表达这一点:SELECT *
FROM table
WHERE structural_type = 1 AND
parent_id ='167F2-F' AND
points_to_id = '' AND
search not like '%donotmatch124213123123%';
索引仍应用于前三列。 LIKE
可能很慢,但是如果没有很多行与前三行匹配,这可能不如使用全文本索引那么糟糕。
由于无法同时运行两个查询以使哪个查询更快,所以它将估计不同的执行计划有多快。
为此,MySQL使用一些内部统计信息保存在每个表中。但是,如果不更新这些统计信息,并且表中的数据发生更改,则这些统计信息可能与实际情况大不相同。
运行OPTIMIZE TABLE table
查询使MySQL可以刷新其表统计信息,因此它将能够执行更好的估计并选择更好的索引。