使用LIKE'string'vs ='string'对Oracle的性能有何影响?
这
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%';
比这慢
SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value';
但是呢?
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value';
我的测试表明第二个和第三个示例完全相同。如果是这样,我的问题是,为什么要使用" ="?
解决方案
签出两者的解释计划。它们生成相同的执行计划,因此对于数据库而言,它们是同一件事。
我们将使用=来测试是否相等,而不是相似性。如果我们也要控制比较值,那么差别不大。如果这是被用户提交,那么"苹果"和"苹果%"会给你很大的不同结果。
你试过了吗?测试是唯一确定的方法。
顺便说一句,这些语句中没有一个肯定会返回相同的行。试用:
insert into some_table (some_field) values ('some_value'); insert into some_table (some_fieled) values ('1some_value2'); insert into some_table (some_field) values ('some1value'); SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%'; SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value'; SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value';
为了清楚起见并避免出现细微的错误,除非我们需要通配符功能,否则最好不要使用LIKE。 (显然,在进行临时查询时,可能还可以。)
像"%WHATEVER%"一样,必须进行完整的索引扫描。
如果没有%,那么它就像一个等号。
如果%在一端,则索引可以是范围扫描。
我不确定优化器如何处理绑定字段。
使用绑定变量时,有一个明显的区别,绑定变量应该在Oracle中用于数据仓库或者其他批量数据操作以外的其他任何操作。
以以下情况为例:
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE :b1
Oracle在执行之前不知道:b1的值为'%some_value%'或者'some_value'等,因此它将根据启发式方法估计结果的基数,并提出一个合适的计划可能适合或者可能不适合:b的各种值,例如'%A','%','A'等。
对于相等谓词,类似的问题也可能适用,但是,例如,基于列统计信息或者唯一约束的存在,可能导致的基数范围更容易估计。
因此,就我个人而言,我不会开始使用LIKE来代替=。优化器有时很容易被愚弄。
If that's true, my question is, why ever use "=" ?
一个更好的问题:如果是这样,为什么要使用" LIKE"来测试是否相等?我们不必再按Shift键,那么阅读脚本的每个人都会感到困惑。
如果没有$%等字符,则like的形式是相同的,因此,发现它具有相同的成本并不奇怪。
我发现David Aldridge的答案很有趣,因为应用程序应该使用绑定变量。使用`%foobar'这样的索引,我们将无法利用索引的顺序。如果查询是预编译的,将导致更多的索引或者表完全扫描。
此外,我发现这样做很危险,因为它可能导致SQL注入和奇怪的错误(例如,如果有一个名为john的用户,黑客可以创建一个名为"'joh $'`"的用户并尝试登录)
为什么要冒险? ''='`更清晰,没有任何问题。