SQL LIKE仅使用通配符(%)作为值的性能

Chr*_*ail 11 sql sql-server oracle derby sql-like

我想知道查询的性能如何使用LIKE关键字和通配符作为与没有where子句的值相比较.

考虑一个where子句,例如"WHERE a LIKE'%'".这将匹配列'a'的所有可能值.这与没有where子句相比如何.

我问这个的原因是我有一个应用程序,其中有一些字段,用户可以指定要搜索的值.在某些情况下,用户希望获得所有可能的结果.我目前正在使用这样的单个查询:

SELECT * FROM TableName WHERE a LIKE ? AND b LIKE ?
Run Code Online (Sandbox Code Playgroud)

可以提供'%'和'%'的值以匹配a和or b的所有可能值.这很方便,因为我可以在我的应用程序中使用单个命名查询.我想知道性能考虑因素是什么.查询优化器是否会将LIKE'%'简化为全部匹配?我意识到因为我正在使用命名查询(预备语句),这也可能影响答案.我意识到答案可能是数据库特定的.具体来说,这将如何在Oracle,MS SQL Server和Derby中发挥作用.

另一种方法是根据用户输入通配符使用3个单独的查询.

A是通配符查询:

SELECT * FROM TableName WHERE b LIKE ?
Run Code Online (Sandbox Code Playgroud)

B是通配符查询:

SELECT * FROM TableName WHERE a LIKE ?
Run Code Online (Sandbox Code Playgroud)

A和B是通配符:

SELECT * FROM TableName
Run Code Online (Sandbox Code Playgroud)

没有通配符:

SELECT * FROM TableName WHERE a LIKE ? AND b LIKE ?
Run Code Online (Sandbox Code Playgroud)

显然,单个查询是最简单和最容易维护的.如果性能仍然良好,我宁愿只使用一个查询.

Rob*_*ley 12

SQL Server一般会看到

WHERE City LIKE 'A%'
Run Code Online (Sandbox Code Playgroud)

并将其视为

WHERE City >= 'A' AND City < 'B'
Run Code Online (Sandbox Code Playgroud)

...并且如果合适的话,愉快地使用索引搜索.我说'一般',因为我看到它在某些情况下没有做到这种简化.

如果有人试图这样做:

WHERE City LIKE '%ville'
Run Code Online (Sandbox Code Playgroud)

......那么索引搜索基本上是不可能的.

但有些事情很简单:

WHERE City LIKE '%'
Run Code Online (Sandbox Code Playgroud)

将被视为等同于:

WHERE City IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

  • DB2(至少)具有反向索引的概念,其中'%ville'易于优化(通过将反转值存储在索引中并在内部将查询更改为'elliv%').您可以使用额外的列和插入/更新触发器在其他DBMS上模拟相同的操作. (2认同)
  • 用于指出`LIKE'%'的+1仅返回具有非空值的行. (2认同)

Chr*_*ail 4

我希望对此有一个教科书的答案,但听起来它会因不同的数据库类型而有很大差异。大多数回复表明我应该进行测试,所以我确实这么做了。

我的应用程序主要针对 Derby、MS SQL 和 Oracle 数据库。由于 derby 可以嵌入式运行并且易于设置,因此我首先测试了其性能。结果令人惊讶。我针对一个相当大的表测试了最坏的情况。我运行了 1000 次测试并取结果的平均值。

查询1:

SELECT * FROM TableName
Run Code Online (Sandbox Code Playgroud)

查询 2(值为 a="%" 和 b="%"):

SELECT * FROM TableName WHERE a LIKE ? AND b LIKE ?
Run Code Online (Sandbox Code Playgroud)

查询1平均时间:178ms

查询2平均时间:181ms

因此,这两个查询在 derby 上的性能几乎相同。