2

我正在创建一份关于 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”并没有花费太多时间。

感谢大家的反馈。:-)

4

3 回答 3

1

也许这top 1部分让 SQL Server 选择了一个特别倒霉的查询计划?尝试:

IF EXISTS (SELECT * FROM VIEW)

如果您发布两个变体的实际查询计划的屏幕截图,它也会有所帮助。

于 2013-08-19T08:06:06.697 回答
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/

为什么 select Top 子句会导致长时间的成本

于 2013-08-19T19:52:51.463 回答
0

你也可以更换

IF EXISTS

有一个比较的查询NULL

因此,您还应该尝试切换语句,例如

IF EXISTS (SELECT TOP 1 * FROM VIEW)

IF (SELECT TOP 1 * FROM VIEW) IS NOT NULL

我记得那曾经帮助过我

于 2013-08-20T09:31:32.597 回答