Oracle使用LIKE'tring'vs ='string'对性能有何影响?

时间:2008-09-25 16:46:36

标签: sql performance 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';

我的测试表明第二和第三个例子完全相同。如果这是真的,我的问题是,为什么要使用“=”?

7 个答案:

答案 0 :(得分:18)

使用绑定变量时会有明显的区别,您应该在Oracle中使用绑定变量,而不是数据仓库或其他批量数据操作。

以:

为例
SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE :b1

Oracle无法知道:b1的值是'%some_value%',或'some_value'等,直到执行时间,因此它会根据启发式估算结果的基数并得出一个合适的计划可能适合或不适合以下各种值:b,例如'%A','%','A'等。

类似的问题可以应用于等式谓词,但例如,基于列统计或存在唯一约束,可以更容易地估计可能产生的基数范围。

所以,我个人不会开始使用LIKE作为=的替代品。优化器有时很容易被愚弄。

答案 1 :(得分:5)

查看两者的EXPLAIN PLAN。它们生成相同的执行计划,因此对于数据库来说,它们是相同的。

您将使用=来测试相等性,而不是相似性。如果您正在控制比较值,那么它并没有太大的区别。如果这是由用户提交的,那么'apple'和'apple%'会给你很多不同的结果。

答案 2 :(得分:3)

  

如果这是真的,我的问题是,为什么   曾经使用“=”?

一个更好的问题:如果这是真的,为什么要使用“LIKE”来测试相等性?你可以保存点击Shift键,每个阅读脚本的人都会感到困惑。

答案 3 :(得分:2)

你试过吗?测试是唯一确定的方法。

顺便说一句,这些语句都不一定会返回相同的行。试试:

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 ,除非您需要它的通配符功能。 (显然,在进行临时查询时,它可能没问题。)

答案 4 :(得分:1)

LIKE'%WHATEVER%'必须进行全索引扫描。

如果没有百分比,那么它就像一个等于。

如果%位于一端,则索引可以是范围扫描。

我不确定优化器如何处理绑定字段。

答案 5 :(得分:1)

如果你没有like等字符,那么

$%正式相同,所以发现它具有相同的成本并不是一个大惊喜。

我发现David Aldridge回答很有趣,因为你的应用程序应该使用绑定变量。使用like '%foobar',您无法在索引中使用排序。如果查询是预编译的,那么将导致更多索引或表格完全扫描。

此外,我发现它很危险,因为它可能导致SQL注入和奇怪的错误(例如,如果有一个名为john的用户,黑客可以创建名为'joh$'的用户并尝试登录)

为什么要承担风险? '='更清楚,没有任何问题。

答案 6 :(得分:0)

1)%和=打算在不同的情况下使用。 即使我们可以在like子句中搜索确切的值并获得所需的结果,在所有此类情况下,仍应使用=。因此,只要我们要搜索确切的值,就应该始终使用=。

2)每当在搜索子句中未提供%时,都会执行like和=的性能: 在所有这样的情况下,查询优化器都会自动将像簇一样转换为=。这可以从查询计划中看出来(请参阅所附的屏幕截图)。因此,在这种情况下,性能应该完全相同。感谢查询优化器!

我正在提供这两个查询的执行计划的屏幕截图,即带有like子句但没有%的查询以及带有like子句和%的查询。

"Make" variable

Checkout page