在`LIKE:varname ||上使用索引 火鸟的'%'`

tjo*_*nko 4 sql database firebird firebird2.5

我有一个问题

SELECT DISTINCT FKDOCUMENT
FROM PNTM_DOCUMENTS_FT_INDEX
WHERE WORD LIKE 'sometext%'
Run Code Online (Sandbox Code Playgroud)

PLAN SORT((PNTM_DOCUMENTS_FT_INDEX INDEX(IX_PNTM_DOCUMENTS_FT_INDEX)))

它工作正常.

但是当我尝试使用连接字符串时LIKE,firebird 不使用标记:

SELECT DISTINCT FKDOCUMENT
FROM PNTM_DOCUMENTS_FT_INDEX
WHERE WORD LIKE 'sometext' || '%'
Run Code Online (Sandbox Code Playgroud)

计划排序((PNTM_DOCUMENTS_FT_INDEX NATURAL))

如何强制它使用指标?

Mar*_*eel 5

正如已经评论过的那样,简短的回答是使用STARTING [WITH]而不是LIKE如果你不需要类似的模式,但总是想要进行前缀搜索.所以:

WHERE WORD STARTING WITH 'sometext' -- No %!
Run Code Online (Sandbox Code Playgroud)

要么

WHERE WORD STARTING WITH :param
Run Code Online (Sandbox Code Playgroud)

据我所知,这正是Firebird所做的LIKE 'sometext%'.这将在可用时使用索引,并且您不需要为了存在类似的模式符号而将其转义.缺点是你不能使用像模式符号.

现在,为什么Firebird在您使用时不使用索引

WHERE WORD LIKE :param || '%' -- (or LIKE :param) for that matter
Run Code Online (Sandbox Code Playgroud)

要么

WHERE WORD LIKE 'sometext' || '%'
Run Code Online (Sandbox Code Playgroud)

第一种情况很容易解释:语句准备与执行分开进行.Firebird需要考虑参数值以a _或 - 更差 - a 开头的可能性%,并且它不能使用索引.

至于第二种情况,它应该可以优化到相当于LIKE 'sometext%',但Firebird可能会认为任何不是普通文字的东西都不可优化.对于这个特定的例子,可以确定它应该是可优化的,但这是一个非常特殊的异常(通常不会像这样连接文字,大多数情况下,一个或多个'黑色'框如列,函数,case语句等涉及).