连接中的TSQL concat非常慢

时间:2013-01-31 15:44:50

标签: tsql sql-server-2012 concat

我们有这样的疑问:

select X.id_x, A.id_a, B.id_b
from X
left join A on 'A|' + A.id_a = X.id_aOrB
left join B on 'B|' + B.id_b = X.id_aOrB

X链接到A或B,id在连接语句中计算。

  • X:8 000行
  • 答:36 000行
  • B:3 000行

此查询非常慢,如10秒。 X.id_aOrb上没有索引。

然后使用2个“连接”表,由触发器更新,我们不需要连接'A|' + id'B|'+id。结果的获取时间不到1秒。行。

我的问题:为什么这个结尾这么慢?当数据太多时,SQL Server在'+'中效率不高吗?

3 个答案:

答案 0 :(得分:1)

FROM X
LEFT JOIN A on 'A|' + A.id_a = X.id_aOrB

不是sargable(SQL Server不能使用索引)。

如果它使用嵌套循环连接,那么它必须扫描AX中的行一样多次。无法对A进行索引搜索以评估'A|' + A.id_a = X.id_aOrB谓词。

如果它使用合并连接,则必须先获取数据的副本并对其进行排序,而不是使用索引中的顺序。

同样适用于B

上的加入

答案 1 :(得分:0)

查看执行计划,看看它花费的时间最多。 SQL正在进行表扫描吗?它们很慢。如果你没有关于X.id_aOrB的索引,那么这将是一个很好的优化。一些关于如何解释执行计划的文章here

如果您要经常运行此查询,可以从中创建一个视图并对其进行索引以使其变为实体化(维护将花费成本......)

答案 2 :(得分:0)

以下查询更快吗?

With t as
(
  select id_x,SUBSTRING(X.id_aOrB,3,1000) as id_a,null as id_b
  from x
  where X.id_aOrB like 'A|%'
  union all
  select id_x,NULL as id_a,SUBSTRING(X.id_aOrB,3,1000) as id_b
  from x
  where X.id_aOrB like 'B|%'
)
select t.id_x, A.id_a, B.id_b
from t
left join A on A.id_a = t.id_a
left join B on B.id_b = t.id_b