fts+复合索引优化查询
Optinimizing query with fts + composite index
我有以下查询:
SELECT *
FROM table
WHERE
structural_type=1
AND parent_id='167F2-F'
AND points_to_id=''
# AND match(search) against ('donotmatch124213123123')
在复合索引(structural_type、parent_id、points_to_id)上搜索 运行、运行 大约需要 10 毫秒。但是,当我添加 fts 索引时,无论匹配条件中包含什么,查询都会膨胀到 ~1s。基本上,每当我应用 fts 搜索时,它似乎都是 'skips the index'。
优化此查询的最佳方法是什么?
更新:几点说明:
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
使用 fts(同时添加 'force index'):
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 中添加一个额外的术语,这样它就可以过滤 'within' 了。例如:
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 优化器只能为您的 WHERE 子句使用一个索引,因此它必须在复合索引和全文索引之间进行选择。
由于它不能运行 两个查询来判断哪个更快,它将估计不同执行计划的速度。
为此,MySQL 使用了它保留的关于每个 table 的一些内部统计数据。但是如果不更新这些统计数据并且 table.
中的数据发生变化,这些统计数据可能与实际情况大不相同
运行 OPTIMIZE TABLE table
查询允许 MySQL 刷新其 table 统计信息,因此它将能够执行更好的估计并选择更好的索引。
我有以下查询:
SELECT *
FROM table
WHERE
structural_type=1
AND parent_id='167F2-F'
AND points_to_id=''
# AND match(search) against ('donotmatch124213123123')
在复合索引(structural_type、parent_id、points_to_id)上搜索 运行、运行 大约需要 10 毫秒。但是,当我添加 fts 索引时,无论匹配条件中包含什么,查询都会膨胀到 ~1s。基本上,每当我应用 fts 搜索时,它似乎都是 'skips the index'。
优化此查询的最佳方法是什么?
更新:几点说明:
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
使用 fts(同时添加 'force index'):
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 中添加一个额外的术语,这样它就可以过滤 'within' 了。例如:
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 优化器只能为您的 WHERE 子句使用一个索引,因此它必须在复合索引和全文索引之间进行选择。
由于它不能运行 两个查询来判断哪个更快,它将估计不同执行计划的速度。
为此,MySQL 使用了它保留的关于每个 table 的一些内部统计数据。但是如果不更新这些统计数据并且 table.
中的数据发生变化,这些统计数据可能与实际情况大不相同运行 OPTIMIZE TABLE table
查询允许 MySQL 刷新其 table 统计信息,因此它将能够执行更好的估计并选择更好的索引。