SQL Server 中 SUBSTRING 与 LEFT 的性能

问题描述 投票:0回答:5

我很好奇是什么让我的查询变慢,我想到了一个问题。

哪一种更快更高效?

LEFT()
还是
SUBSTRING()

sql sql-server
5个回答
22
投票

left
substring
之间没有任何区别,因为
left
在执行计划中被翻译为
substring

例如:

select substring(col, 1, 2),
       left(col, 3)
from YourTable

在执行计划中看起来像这样

<DefinedValue>
  <ColumnReference Column="Expr1004" />
  <ScalarOperator ScalarString="substring([col],(1),(2))">
    <Intrinsic FunctionName="substring">
      <ScalarOperator>
        <Identifier>
          <ColumnReference Column="col" />
        </Identifier>
      </ScalarOperator>
      <ScalarOperator>
        <Const ConstValue="(1)" />
      </ScalarOperator>
      <ScalarOperator>
        <Const ConstValue="(2)" />
      </ScalarOperator>
    </Intrinsic>
  </ScalarOperator>
</DefinedValue>
<DefinedValue>
  <ColumnReference Column="Expr1005" />
  <ScalarOperator ScalarString="substring([col],(1),(3))">
    <Intrinsic FunctionName="substring">
      <ScalarOperator>
        <Identifier>
          <ColumnReference Column="col" />
        </Identifier>
      </ScalarOperator>
      <ScalarOperator>
        <Const ConstValue="(1)" />
      </ScalarOperator>
      <ScalarOperator>
        <Const ConstValue="(3)" />
      </ScalarOperator>
    </Intrinsic>
  </ScalarOperator>
</DefinedValue>

18
投票

SQL Server 是一个数据库。您不会询问哪个字符串处理函数“更快”。你问“哪些可以使用索引?”的问题以及“我有所需的索引吗?”。都是关于数据访问的,因为磁盘太慢了,而不是关于移动 CPU 寄存器。

那么,哪个可以使用索引?(哪个是sargable?)。理论上

LEFT
可以使用索引,但实际上通常不会。
SUBSTRING
不能。使用
全文
代替 SUBSTRING

设计您的数据模型以利用可控制表达式,并相应地建立索引。仅此而已,没有灵丹妙药。避免扫描。


11
投票

这是一篇好文章,如果有人感兴趣的话,它对 SUBSTRING、LIKE、CHARINDEX 和 LEFT/RIGHT 之间的性能进行了基准测试。

根据结果,在非索引列上,LEFT/RIGHT 始终比 SUBSTRING 快。


3
投票

当您在谓词上使用函数时,您的引擎将被迫使用 Scan 操作而不是 Seek 操作。理论上,左派倾向于巧妙地使用索引。但是,您的引擎在执行之前仍然不知道 Left() 函数的输出。所以,Substring() 也是一样的。

如果您确实想调整查询的性能,可以将 Left() 表达式替换为 LIKE 表达式。确保末尾有 % 通配符。该表达式将使用 Index Seek(如果列上有适当的索引)。

例如,

Left(MyColumn, 2) = 'AB' >> MyColumn LIKE 'AB%'

实际上,LIKE 运算符(末尾带有 % 通配符)最终被引擎转换为逻辑查找谓词。因此,上面的 LIKE 表达式将被引擎重写如下,

MyColumn LIKE 'AB%' >> MyColumn >= 'AB' 和 MyColumn < 'AC'

对于 Substring(),你没有更好的替代方案,你必须考虑其他替代方案,例如全文。


1
投票

这样的桌子

Id_num  Fname    Minit      Lname       ids
1    Karin    F     Josephs      3
2    Pirkko   O     Koskitalo       56
3        Karin    F     Josephs     16
4        Pirkko   O     Koskitalo        96
1        Karin    F     Josephs      3
2    Pirkko   O     Koskitalo        56

子串:

使用

SUBSTRING
,提供初始位置值和结束位置值。

例如:

select SUBSTRING(Fname,2,5) from new_employees
(No column name)
arin
irkko
arin
irkko
arin
irkko

左:

使用

left
仅给出您想要从左侧获得的字符数。

例如:

select left(Fname,2) from new_employees

(No column name)
Ka
Pi
Ka
Pi
Ka
Pi
© www.soinside.com 2019 - 2024. All rights reserved.