SQL 带 LIKE 的参数 ?% 强制使用索引

SQL parameters with LIKE ?% force use index

当我只想在像 foo% 这样的词后使用通配符搜索时,我如何在使用 LIKE(也许是更好的解决方案?)和参数绑定时强制使用索引?请参阅使用和不使用参数绑定的示例。我想防止参数示例中的tableScan。

我正在使用带有 H2 数据库的 SpringBoot 应用程序。

不带参数的查询:

SELECT * 
FROM (SELECT resource_id FROM SEARCH_TABLE_874 WHERE word LIKE 'su%')
 GROUP BY resource_id ORDER BY COUNT (*) DESC LIMIT 100

执行计划:

SELECT
    _1.RESOURCE_ID
FROM (
    SELECT
        RESOURCE_ID
    FROM PUBLIC.SEARCH_TABLE_874
    WHERE WORD LIKE 'su%'
) _1
    /* SELECT
        RESOURCE_ID
    FROM PUBLIC.SEARCH_TABLE_874
        /++ PUBLIC.IDX_SEARCH_TABLE_874_WORD: WORD >= 'su'
            AND WORD < 'sv'
         ++/
    WHERE WORD LIKE 'su%'
     */
GROUP BY RESOURCE_ID
ORDER BY =COUNT(*) DESC
LIMIT 100`

带参数查询:

`SELECT * FROM (SELECT resource_id FROM SEARCH_TABLE_874 WHERE word LIKE :param) GROUP BY resource_id ORDER BY COUNT (*) DESC LIMIT 100`

执行计划:

`SELECT
    _10.RESOURCE_ID
FROM (
    SELECT
        RESOURCE_ID
    FROM PUBLIC.SEARCH_TABLE_874
    WHERE WORD LIKE CONCAT(?1, '%')
) _10
    /* SELECT
        RESOURCE_ID
    FROM PUBLIC.SEARCH_TABLE_874
        /++ PUBLIC.SEARCH_TABLE_874.tableScan ++/
    WHERE WORD LIKE CONCAT(?1, '%')
     */
GROUP BY RESOURCE_ID
ORDER BY =COUNT(*) DESC
LIMIT 100

查询来源的更多详细信息:

这是一个搜索引擎。

Query被代码生成为String,然后像String一样执行:

Query query = session.createNativeQuery(queryString);
query.setParameter("param", "foo%");
query.getFirstResult()

对于执行计划,我在查询前写了 EXPLAIN。该结构是因为可以通过 UNION 进行许多子选择。

解决方案在不带参数的查询的执行计划中。我现在使用 WORD >= 'foo' AND WORD < 'fop' 而不是 LIKE 'foo%。这样数据库就可以使用索引了。