我们有这样的查询:
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在"+"中不是很有效吗?
FROM X
LEFT JOIN A on 'A|' + A.id_a = X.id_aOrB
不可优化优化处理(SQL Server 不能使用索引)。
如果它使用嵌套循环连接,那么它必须扫描A
与X
中的行一样多的次数。无法对A
进行索引查找以评估'A|' + A.id_a = X.id_aOrB
谓词。
如果它使用合并联接,它必须首先获取数据的副本并对其进行排序,而不是能够使用索引中的顺序。
当然,这同样适用于B
查看执行计划,看看它花费的时间最多。SQL 是否在执行表扫描?它们非常慢。 如果您没有索引X.id_aOrB那么这将是一个很好的优化。有关如何解释执行计划的一些文章。
如果您要经常运行此查询,则可以从中创建视图并为其编制索引,以便将其具体化(尽管维护会花费...
以下查询是否更快?
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