在 `LIKE :varname || 上使用索引火鸟中的“%”

问题描述 投票:0回答:1

我有疑问

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))

如何强制它使用索引?

sql firebird sql-like
1个回答
6
投票

简短的答案,正如已经评论的那样,如果您不需要类似的模式,但总是想进行前缀搜索,则使用

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 语句等涉及)。

© www.soinside.com 2019 - 2024. All rights reserved.