【发布时间】:2014-11-25 00:14:04
【问题描述】:
我注意到在 SQL Server (2008 R2) 中运行以下代码需要 32 秒
IF ((SELECT COUNT(*) FROM view1) != 0)
OR ((SELECT COUNT(*) FROM view2) != 0)
OR ((SELECT COUNT(*) FROM view3) != 0)
OR ((SELECT COUNT(*) FROM view4) != 0)
OR ((SELECT COUNT(*) FROM view5) != 0)
OR ((SELECT COUNT(*) FROM view6) != 0)
PRINT 'HI'
然而,以下只用了 4 秒
SELECT
(SELECT COUNT(*) FROM view1)
, (SELECT COUNT(*) FROM view2)
, (SELECT COUNT(*) FROM view3)
, (SELECT COUNT(*) FROM view4)
, (SELECT COUNT(*) FROM view5)
, (SELECT COUNT(*) FROM viwe6)
我已经设法通过执行 SELECT COUNT(1)... + SELECT... != 0 来优化条件,这需要 4 秒,但查看执行计划并没有产生任何特别值得注意的结果。也没有太多机会用谷歌搜索这个词。
有人可以分享一下 SQL Server 优化器可能在背后做什么吗?
编辑:IF EXISTS 尝试耗时 38 秒。
IF EXISTS ((SELECT 1 FROM view1)
UNION (SELECT 1 FROM view2)
UNION (SELECT 1 FROM view3)
UNION (SELECT 1 FROM view4)
UNION (SELECT 1 FROM view5)
UNION (SELECT 1 FROM view6))
PRINT 'HI'
EDIT2:当前的 5 秒方法。
IF (SELECT COUNT(1) FROM view1)
+ (SELECT COUNT(1) FROM view2)
+ (SELECT COUNT(1) FROM view3)
+ (SELECT COUNT(1) FROM view4)
+ (SELECT COUNT(1) FROM view5)
+ (SELECT COUNT(1) FROM viwe6) != 0
PRINT 'HI'
EDIT3:在比较了 20 页大小的查询计划之后 - 似乎加速主要是由于底层视图在它们的连接之前进行部分聚合,而不是先连接然后聚合。
【问题讨论】:
-
执行 EXISTS( SELECT 1 FROM view1 ) 可以获得更好的性能,因为它会在找到一行后停止查看,而不是计算所有行。
-
我确实尝试过 EXISTS。但这也花了大约 38 秒。我会将我尝试过的内容放入编辑中。
-
快速思考将计数结果放入变量然后使用 IF 条件
-
-
嵌套视图可能会导致查询优化器出现问题,尤其是当它们深入时。经验法则是遵循百分比并单独攻击大百分比。
标签: sql sql-server tsql query-optimization