使用 CROSS APPLY 进行慢速查询

Posted

技术标签:

【中文标题】使用 CROSS APPLY 进行慢速查询【英文标题】:Slow query with CROSS APPLY 【发布时间】:2017-11-09 12:02:12 【问题描述】:

我有以下 SQL 代码,需要几秒钟才能执行:

SELECT instance.startdate
      ,instance.enddate 
FROM (select mr.id 
      FROM meeting_recurrence AS mr 
      inner JOIN meeting_details md ON md.id = mr.meeting_template_id 
      WHERE host_user_id=17) AS p 
CROSS APPLY GetRecurrenceMeetingInstances(p.id,'2018-11-09 11:00:00','2018-11-09 15:00:00') AS instance  
WHERE 21015 IS NOT NULL 
AND instance.meetingid <> 21015

上例中的内部选择(select mr.id FROM meeting_recurrence...) 立即返回,带有两个id。

分别使用这两个 id 运行 GetRecurrenceMeetingInstances(),立即返回空结果。

与单独运行相比,为什么运行整个语句需要这么长时间?

执行计划图片:https://imgur.com/a/3Ydym

【问题讨论】:

你检查过执行计划吗? 发布执行计划就好了 WHERE 21015 IS NOT NULL 应该做什么? 21015 是列名吗?如果是这样,它不会被解释为这样,它被解释为一个整数,因此它不能是NULL 我在 MS Management Studio 中有一个大型 XML 文件的执行计划。如何发布? 还有图形表示 【参考方案1】:

似乎 CROSS APPLY 调用 GetRecurrenceMeetingInstances() 的次数比我想象的要多得多。我通过首先将内部选择保存在局部变量中解决了这个问题:

DECLARE @innerresult table(meetingid int)
INSERT INTO @innerresult(meetingid) (select mr.id FROM meeting_recurrence AS mr inner JOIN meeting_details md ON md.id = mr.meeting_template_id 
    WHERE host_user_id=17)

INSERT INTO @timeslots (startdate,enddate) 
    SELECT instance.startdate,instance.enddate 
    FROM (select meetingid FROM @innerresult) AS p 
    CROSS APPLY GetRecurrenceMeetingInstances(p.meetingid,'2018-11-09 11:00:00','2018-11-09 15:00:00') AS instance  

【讨论】:

以上是关于使用 CROSS APPLY 进行慢速查询的主要内容,如果未能解决你的问题,请参考以下文章

使用 CROSS APPLY 与 OUTER APPLY 连接查询

使用 CROSS APPLY 与 OUTER APPLY 连接查询

使用 CROSS APPLY 与 OUTER APPLY 连接查询

将相关子查询重写为 CROSS APPLY

Hive 上的 CROSS APPLY SQL Server 查询

CROSS APPLY 风格与性能