在 `LIKE :varname || 上使用索引火鸟中的“%”
Using index on `LIKE :varname || '%'` in firebird
我有一个问题
SELECT DISTINCT FKDOCUMENT
FROM PNTM_DOCUMENTS_FT_INDEX
WHERE WORD LIKE 'sometext%'
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' || '%'
PLAN SORT ((PNTM_DOCUMENTS_FT_INDEX NATURAL))
如何强制使用索引?
简短的回答,正如我已经评论过的那样,如果您不需要类似的模式,但总是想进行前缀搜索,则使用 STARTING [WITH]
而不是 LIKE
。所以:
WHERE WORD STARTING WITH 'sometext' -- No %!
或
WHERE WORD STARTING WITH :param
据我所知,这正是 Firebird 使用 LIKE 'sometext%'
所做的。这将在可用时使用索引,并且您无需为存在类似模式符号而将其转义。缺点是不能使用 like 模式符号。
现在关于为什么当你使用
时 Firebird 不使用索引
WHERE WORD LIKE :param || '%' -- (or LIKE :param) for that matter
或
WHERE WORD LIKE 'sometext' || '%'
第一种情况很容易解释:语句准备与执行分开进行。 Firebird 需要考虑参数值以 _
或 - 更糟 - %
开头的可能性,并且它不能为此使用索引。
至于第二种情况,应该可以将其优化为 LIKE 'sometext%'
的等价物,但 Firebird 可能认为任何不是普通文字的东西都不可优化。对于这个具体的例子,有可能决定它应该是可优化的,但这是一个非常具体的例外(通常不会像这样连接文字,大多数时候一个或多个 'black' 框,如列,函数,涉及案例陈述等)。
我有一个问题
SELECT DISTINCT FKDOCUMENT
FROM PNTM_DOCUMENTS_FT_INDEX
WHERE WORD LIKE 'sometext%'
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' || '%'
PLAN SORT ((PNTM_DOCUMENTS_FT_INDEX NATURAL))
如何强制使用索引?
简短的回答,正如我已经评论过的那样,如果您不需要类似的模式,但总是想进行前缀搜索,则使用 STARTING [WITH]
而不是 LIKE
。所以:
WHERE WORD STARTING WITH 'sometext' -- No %!
或
WHERE WORD STARTING WITH :param
据我所知,这正是 Firebird 使用 LIKE 'sometext%'
所做的。这将在可用时使用索引,并且您无需为存在类似模式符号而将其转义。缺点是不能使用 like 模式符号。
现在关于为什么当你使用
时 Firebird 不使用索引WHERE WORD LIKE :param || '%' -- (or LIKE :param) for that matter
或
WHERE WORD LIKE 'sometext' || '%'
第一种情况很容易解释:语句准备与执行分开进行。 Firebird 需要考虑参数值以 _
或 - 更糟 - %
开头的可能性,并且它不能为此使用索引。
至于第二种情况,应该可以将其优化为 LIKE 'sometext%'
的等价物,但 Firebird 可能认为任何不是普通文字的东西都不可优化。对于这个具体的例子,有可能决定它应该是可优化的,但这是一个非常具体的例外(通常不会像这样连接文字,大多数时候一个或多个 'black' 框,如列,函数,涉及案例陈述等)。