我们有这样的疑问:
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在连接语句中计算。
此查询非常慢,如10秒。 X.id_aOrb
上没有索引。
然后使用2个“连接”表,由触发器更新,我们不需要连接'A|' + id
和'B|'+id
。结果的获取时间不到1秒。行。
我的问题:为什么这个结尾这么慢?当数据太多时,SQL Server在'+'中效率不高吗?
答案 0 :(得分:1)
FROM X
LEFT JOIN A on 'A|' + A.id_a = X.id_aOrB
不是sargable(SQL Server不能使用索引)。
如果它使用嵌套循环连接,那么它必须扫描A
与X
中的行一样多次。无法对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