我正在创建一份关于SSRS 2008 R2的报告。只有在数据存在时才会发送此报告。起初,我尝试创建数据驱动的订阅,调用存储过程来检查视图是否有数据。如果是这样,它会将报告发送给定义的收件人。由于用户要求每10分钟检查一次视图,我设置了一个作业来在SQL Server代理上执行此数据驱动订阅的作业名称。但我发现订阅总是超时,即使直接选择视图只需要大约二十到三十秒。
然后我试着想出其他方式来满足这个要求。
我尝试的方法是在SQL Server上创建一个存储过程,以检查视图是否首先包含数据。如果是,它将运行为SSRS 2008 R2上的报告创建的订阅的作业名称。为了每10分钟检查一次视图,我在SQL Server Angent上每10分钟创建一个执行此SP的作业。
问题是为什么用“IF EXISTS”执行SP1需要大约20分钟,而用“COUNT(*)”执行SP2只需要20秒。我真的很困惑。
感谢您的回复。 :)
SP1:
IF EXISTS (SELECT TOP 1 * FROM VIEW)
BEGIN
EXEC msdb.dbo.sp_start_job
@job_name = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
END
--
IF EXISTS (SELECT TOP 1 C1 FROM VIEW ORDER BY C1)
BEGIN
EXEC msdb.dbo.sp_start_job
@job_name = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
END
--
IF EXISTS (SELECT C1 FROM VIEW)
BEGIN
EXEC msdb.dbo.sp_start_job
@job_name = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
END
SP2:
DECLARE @ExecRowCount INT
CREATE TABLE #Temp
(
C1 CHAR(50),
C2 DECIMAL(10,0),
C3 CHAR(50),
C4 VARCHAR(4)
)
INSERT INTO #Temp
SELECT * FROM VIEW
SELECT @ExecRowCount = COUNT(*) FROM #Temp
DROP TABLE #Temp
IF(@ExecRowCount > 0)
BEGIN
EXEC msdb.dbo.sp_start_job
@job_name='xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
END
SP3:
IF ((SELECT COUNT(*) FROM VIEW) > 0)
BEGIN
EXEC msdb.dbo.sp_start_job
@job_name = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
END
编辑2013/08/20: 我添加了我在SP1和SP3 @ Click-Rex建议的其他条款。
抱歉,我忘了提到视图是在SQL 2000上。这是我将此视图的相关数据库恢复到SQL 2008 QAS后尝试的问题的根本原因。恢复后我没有更改任何设置。
结果是: SP1和SP3的时间不到1秒,SP2的时间不到20秒。
实际上,这种观点非常复杂。我在SQL 2000上尝试了其他简单的视图。“IF EXISTS”并没有花费太多时间。
感谢大家的反馈。 : - )
答案 0 :(得分:1)
也许top 1
部分使SQL Server选择了一个特别不幸的查询计划?尝试:
IF EXISTS (SELECT * FROM VIEW)
如果您发布两种变体的实际查询计划的屏幕截图,也会有所帮助。
答案 1 :(得分:0)
尝试这样的事情:
IF EXISTS (SELECT TOP 1 * FROM VIEW ORDER BY 1)
已知TOP N查询存在问题。这里有一些文章供你研究
http://use-the-index-luke.com/sql/partial-results/top-n-queries
http://sqlity.net/en/908/top-n-sort-a-little-bit-of-sorting/
答案 2 :(得分:0)
您也可以替换
IF EXISTS
使用与NULL
所以你也应该尝试切换像
这样的语句IF EXISTS (SELECT TOP 1 * FROM VIEW)
与
IF (SELECT TOP 1 * FROM VIEW) IS NOT NULL
我记得曾经偶尔帮助过我