sql语句是两个查询之间的简单联合。每一个都是瞬间的。然而联合所有它们变得慢20倍。任何帮助表示赞赏。
SELECT
1
FROM
[fnGetEmployeeProfileDoctorsMultiplePeriods](
@FromPeriodId,
@ToPeriodId,
@ProfileId,
@EmployeeId,
@GeographicalAreaId,
@DoctorId,
@TeamId
)
UNION ALL
SELECT
1
FROM
[fnGetEmployeeProfileOrganizationsMultiplePeriods](
@FromPeriodId,
@ToPeriodId,
@ProfileId,
@EmployeeId,
@GeographicalAreaId,
@DoctorId,
@TeamId
)
更新:
似乎添加union运算符会导致两个子查询的执行计划发生变化;查询引擎不会简单地连接两个原始计划。使用选项重新编译标志可以修复此问题(或者更确切地说,创建一个更快的计划),那么如何强制它使用重新编译的计划呢?
计划链接:
慢速版
https://www.brentozar.com/pastetheplan/?id=SyZq2Ybbb
带选项(重新编译)的快速版本设置
https://www.brentozar.com/pastetheplan/?id=HJ5bpYbZZ
更新2:
在两个子查询中进行了大量优化后,症状仍然存在,但现在执行计划在添加union运算符时不会更改。此外,如果您以仅从第一个子查询获得结果的方式使用顶级运算符(或者,令人惊讶,只有第二个子查询),结果会立即返回。然而,“越过边界”并请求两者的结果,并加上5秒的罚款。
答案 0 :(得分:1)
我打赌你的表值函数是多语句表值函数。如果可能,将它们重写为内联表值函数。
内联表值函数与标量和多语句表值函数
“如果它不是内联的,那就是垃圾。” - Rob Farley
参考:
答案 1 :(得分:1)
您是否尝试将每个函数插入临时表,然后查询临时表?例如,您将创建临时表,然后为每个函数分别使用插入语句。
CREATE TABLE #Employee
(
Record INT
)
INSERT INTO #Employee
( Record )
SELECT 1
FROM [fnGetEmployeeProfileDoctorsMultiplePeriods](@FromPeriodId, @ToPeriodId, @ProfileId, @EmployeeId, @GeographicalAreaId, @DoctorId, @TeamId)
INSERT INTO #Employee
( Record )
SELECT 1
FROM [fnGetEmployeeProfileOrganizationsMultiplePeriods](@FromPeriodId, @ToPeriodId, @ProfileId, @EmployeeId, @GeographicalAreaId, @DoctorId, @TeamId)
SELECT *
FROM #Employee
答案 2 :(得分:1)
感谢所有贡献的人。
对此的研究为我打开了庞大的SQL查询优化领域。我的意思是我深入研究了索引视图,sql提示(noexpand,merge / hash join等等)和物化分层表。这是一次忙碌的旅程。
答案 3 :(得分:0)
我遇到了同样的问题。
--Requete 67. Performance cost 6%
SELECT *
INTO #temp_arbo_of_6
FROM (
SELECT * FROM #temp_arbo_of_4
UNION ALL
SELECT * FROM #temp_arbo_of_5
) AS tmp;
每个表有60列。占用分析存储过程的全局计时的6%。不应该。
以这种方式解决:
--Requete 67. Performance cost 0%
INSERT INTO #temp_arbo_of_4
SELECT * FROM #temp_arbo_of_5;
,然后使用#temp_arbo_of_4而不是#temp_arbo_of_6。我不需要两者。