Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 条件连接的性能_Performance_Sql Server 2008_Join_Conditional - Fatal编程技术网

Performance 条件连接的性能

Performance 条件连接的性能,performance,sql-server-2008,join,conditional,Performance,Sql Server 2008,Join,Conditional,我对以下查询的性能有疑问: DECLARE @detail_level INT = 1, @DETAIL_1 INT = 1, @DETAIL_2 INT = 2, @DETAIL_3 INT = 4 SELECT mtbl.*, CASE WHEN @detail_level & @DETAIL_1 <> 0 THEN tbl_1.value ELSE

我对以下查询的性能有疑问:

DECLARE @detail_level INT = 1,
        @DETAIL_1     INT = 1,
        @DETAIL_2     INT = 2,
        @DETAIL_3     INT = 4

SELECT mtbl.*,
       CASE
         WHEN @detail_level & @DETAIL_1 <> 0 THEN tbl_1.value
         ELSE NULL
       END,
       CASE
         WHEN @detail_level & @DETAIL_2 <> 0 THEN tbl_2.value
         ELSE NULL
       END,
       CASE
         WHEN @detail_level & @DETAIL_3 <> 0 THEN tbl_3.value
         ELSE NULL
       END
FROM   mtbl
       LEFT OUTER JOIN tbl_1
         ON @detail_level & @DETAIL_1 <> 0
            AND mtbl.KEY = tbl_1.KEY
       LEFT OUTER JOIN tbl_2
         ON @detail_level & @DETAIL_2 <> 0
            AND mtbl.KEY = tbl_2.KEY
       LEFT OUTER JOIN tbl_3
         ON @detail_level & @DETAIL_3 <> 0
            AND mtbl.KEY = tbl_3.KEY
WHERE  mtbl.KEY = @something 
DECLARE@detail\u level INT=1,
@详图1 INT=1,
@详图2 INT=2,
@详图3 INT=4
选择mtbl.*,
案例
当@detail_level和@detail_1为0时,则tbl_1.0值
否则无效
完,,
案例
当@detail_level和@detail_2为0时,则tbl_2.value
否则无效
完,,
案例
当@detail_level和@detail_3.0时,则tbl_3.0值
否则无效
结束
来自mtbl
左外连接tbl_1
在@detail_级别和@detail_1 0
和mtbl.KEY=tbl_1.KEY
左外连接tbl_2
在@detail_级别和@detail_2 0
和mtbl.KEY=tbl_2.KEY
左外连接tbl_3
在@detail_级别和@detail_3 0
和mtbl.KEY=tbl_3.KEY
其中mtbl.KEY=@something
查询引擎是否会通过使用详细程度过滤器优化查询,以避免不必要的表联接和对这些详细程度表列不必要的表行访问

如果是,查询引擎甚至不会为那些不必要的表获取索引锁吗


我在SQLServer2008中捕获了查询计划,索引搜索操作仍然存在,即使细节级别不匹配。但是,与具有完整详细信息的查询(数据量~500000)相比,具有较少详细信息的查询速度要快(~30%)。

SQL Server将创建一个查询计划,该计划将适用于任何参数值。但它将针对遇到的参数的第一个版本进行优化。这称为“参数嗅探”

您可以使用
选项(重新编译)
查询提示强制重新编译。重新编译会使查询时间增加20-30ms,但查询计划将针对特定的参数值进行优化

另一种选择是使用动态SQL生成一个只连接所需表的查询。这将导致多个缓存的执行计划。这是最好的,但代价是难以维护

作为旁注,当没有任何行与
on
条件匹配时,左联接表的列被设置为
null
。因此,您可以缩短:

case when @detail_level & @DETAIL_1 <> 0 then tbl_1.value else null end

您需要检查执行计划以确定。当我创建以下示例表时

CREATE TABLE tbl_1([KEY] INT PRIMARY KEY, value INT)
CREATE TABLE tbl_2([KEY] INT PRIMARY KEY, value INT)
CREATE TABLE tbl_3([KEY] INT PRIMARY KEY, value INT)
CREATE TABLE mtbl([KEY] INT PRIMARY KEY, value INT)

INSERT INTO mtbl VALUES(1,1),(2,2) 
INSERT INTO tbl_1 VALUES(1,1),(2,2)
INSERT INTO tbl_2 VALUES(1,1),(2,2)
INSERT INTO tbl_3 VALUES(1,1),(2,2)
您的查询给出了执行计划

虽然该显示了针对所有四个相同成本表的操作,但这有点误导。其中只有两个是实际访问的。(即使在实际执行计划中显示的成本也只是估计成本。)

运行
后,打开统计IO,您的示例查询返回

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tbl_1'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'mtbl'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
如您所见,结果中既没有
tbl_2
也没有
tbl_3
功能。查看
tbl_3
上的索引seek的属性表明,从未执行过此运算符(执行次数=0)

这是因为外部联接位于具有启动谓词的筛选器下面,并且仅在其计算结果为true时调用

关于锁定问题,不会对
tbl_2
tbl_3
设置行锁或页锁,但仍会对对象设置
IS
锁。这可以通过运行来看到

DBCC TRACEON(1200,3604,-1)
/*Your query*/ 
DBCC TRACEOFF(1200,3604,-1)

锁与模式修改、批量更新或对象上的独占锁一起使用。

有一个用于数据库问题的堆栈交换sit。你可能会得到一个更好的答案。。。至于这个问题,db2有一个查询分析器。。。我认为sqlserver也有同样的功能。这应该能回答你的问题谢谢你详细的回答。我知道。我之所以在这里写这篇文章,是为了说明这些case子句是否可以避免更少的表访问。例如,如果tbl_1中有许多列,我使用详细级别来控制某些列的访问。我能取得更好的成绩吗?谢谢
DBCC TRACEON(1200,3604,-1)
/*Your query*/ 
DBCC TRACEOFF(1200,3604,-1)