会
WHERE substr(my_field,1,6) = 'search'
或
WHERE my_field LIKE 'search%'
在Oracle中更快,还是没有区别?
答案 0 :(得分:20)
假设最高性能是目标,我最好选择SUBSTR(my_field,1,6)
并创建一个基于函数的索引来支持查询。
CREATE INDEX my_substr_idx
ON my_table( substr( my_field,1,6 ) );
正如其他人指出的那样,SUBSTR(my_field,1,6)
无法在MY_FIELD
上使用常规索引。 LIKE版本可能使用索引,但在这种情况下优化器的基数估计通常相当差,因此很可能在有用时不使用索引,或者在表扫描更可取时使用索引。索引实际表达式将为优化器提供更多信息,因此更有可能正确选择索引。比我聪明的人可能能够建议一种方法来使用11g中的虚拟列统计信息来为优化器提供更好的LIKE查询信息。
如果6是一个变量(即你有时想搜索前6个字符,有时想搜索不同的数字),你可能无法提出基于函数的索引来支持该查询。在这种情况下,你可能会更好地利用LIKE公式中的优化器决策的变幻莫测。
答案 1 :(得分:9)
在提供的两个选项中,绝对是喜欢的。必须对表中的所有行执行substring方法。使用LIKE将允许使用索引。
要检查我的答案,只需分析结果。应该清楚这一天。
答案 2 :(得分:2)
如果my_field上有索引,那么LIKE可能会更快。做自己的基准测试。
答案 3 :(得分:2)
如果你有没有索引而没有差别。因为oracle正在进行全表扫描并评估每行的表达式。 您可以在列上放置索引以加快查询速度。
CREATE INDEX my_like_idx
ON my_table( my_field );
此索引更灵活,可以使用like来加快查询速度。它适用于从字符开始并在结尾处有占位符(%)的任何比较。 Oracle正在进行索引范围扫描以查找所有匹配的行。
CREATE INDEX my_substr_idx
ON my_table( substr( my_field,1,6 ) );
此索引使用substr加速查询。但索引非常特殊,只比较前6个字符。
如果你在中间查询一块。创建基于函数的索引将有所帮助。
WHERE substr(my_field,2,5) = 'earch'
WHERE my_field like '%earch%'
答案 4 :(得分:1)
这里真的有两个问题:
这可能因版本而异,但两者都非常容易测试,因此您可以确保获得最适合您的版本和数据的信息。
使用...
运行两个查询的执行计划explain plan for
select ... from ... where my_field LIKE 'search%';
select * from table(dbms_xplan.display);
和
explain plan for
select ... from ... where substr(my_field,1,6) = 'search';
select * from table(dbms_xplan.display);
您可能会看到执行计划的差异,具体取决于索引的存在等,但也会将基数估算值与您获得的实际结果进行比较:
select count(*) from ... where my_field LIKE 'search%';
这两种方法中的一种可能比另一种方法更准确。
如果它们都不是非常准确和这个查询预计会运行非常重要的时间,那么考虑使用动态采样来改进估计,因为错误的基数估计优化器无论如何,可能会选择次优的访问方法。
explain plan for
select /*+ dynamic_sampling(4) */ ... from ... where substr(my_field,1,6) = 'search';
select * from table(dbms_xplan.display);
就索引使用而言,两种方法都可以使用基于索引的访问方法。 LIKE谓词可能更友好,可以使用范围扫描或快速全索引扫描。 SUBSTR方法当然可以使用快速全索引扫描,但是优化器是否会考虑范围扫描最好在您自己的版本上进行测试 - 我的回忆是它不会,但是谁会说substr(my_column, 1 ,n)不会被认为是特殊情况,如果现在不是将来呢?
答案 5 :(得分:0)
我会介绍两者。但我猜测'LIKE'会快得多,因为它在索引上使用二进制搜索(如果字段被索引)。如果使用SUBSTR方法,最终将进行全表扫描,因为Oracle必须逐行处理该函数。