我有疑问
SELECT DISTINCT FKDOCUMENT
FROM PNTM_DOCUMENTS_FT_INDEX
WHERE WORD LIKE 'sometext%'
计划排序 ((PNTM_DOCUMENTS_FT_INDEX 索引 (IX_PNTM_DOCUMENTS_FT_INDEX)))
而且效果还不错。
但是,当我尝试使用
LIKE
连接字符串时,Firebird 不使用索引:
SELECT DISTINCT FKDOCUMENT
FROM PNTM_DOCUMENTS_FT_INDEX
WHERE WORD LIKE 'sometext' || '%'
计划排序((PNTM_DOCUMENTS_FT_INDEX NATURAL))
如何强制它使用索引?
简短的答案,正如已经评论的那样,如果您不需要类似的模式,但总是想进行前缀搜索,则使用
STARTING [WITH]
而不是 LIKE
。所以:
WHERE WORD STARTING WITH 'sometext' -- No %!
或
WHERE WORD STARTING WITH :param
据我所知,这正是 Firebird 对
LIKE 'sometext%'
所做的事情。这将在可用时使用索引,并且您不需要因存在类似模式符号而对其进行转义。缺点是你不能使用类似的图案符号。
现在说说为什么 Firebird 在使用时不使用索引
WHERE WORD LIKE :param || '%' -- (or LIKE :param) for that matter
或
WHERE WORD LIKE 'sometext' || '%'
第一种情况很容易解释:语句准备与执行分开完成。 Firebird 需要考虑参数值以
_
或更糟糕的 - %
开头的可能性,并且它不能为此使用索引。
对于第二种情况,应该可以将其优化为相当于
LIKE 'sometext%'
,但Firebird可能认为任何不是普通文字的东西都是不可优化的。对于这个具体的例子,可以决定它应该是可优化的,但这是一个非常具体的例外(通常不会像这样连接文字,大多数时候是一个或多个“黑”框,如列、函数、case 语句等涉及)。