Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.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
是";其中(ParamID=@ParamID)或(@ParamID=-1)";sql选择的良好实践_Sql_Sql Server_Performance_Filter_Database Performance - Fatal编程技术网

是";其中(ParamID=@ParamID)或(@ParamID=-1)";sql选择的良好实践

是";其中(ParamID=@ParamID)或(@ParamID=-1)";sql选择的良好实践,sql,sql-server,performance,filter,database-performance,Sql,Sql Server,Performance,Filter,Database Performance,我以前写过sql语句,比如 select * from teacher where (TeacherID = @TeacherID) OR (@TeacherID = -1) 并通过@TeacherID value=-1选择所有教师 现在我担心的是性能 你能告诉我这是个好习惯还是坏习惯吗 非常感谢我们在存储过程中以非常有限的方式使用它 问题是数据库引擎无法为其保留良好的查询计划。在处理大量数据时,这可能会对性能产生严重的负面影响 然而,对于较小的数据集(我会说少于1000条记录,但这是一个猜

我以前写过sql语句,比如

select * from teacher where (TeacherID = @TeacherID) OR (@TeacherID = -1)

并通过@TeacherID value=-1选择所有教师

现在我担心的是性能 你能告诉我这是个好习惯还是坏习惯吗


非常感谢

我们在存储过程中以非常有限的方式使用它

问题是数据库引擎无法为其保留良好的查询计划。在处理大量数据时,这可能会对性能产生严重的负面影响

然而,对于较小的数据集(我会说少于1000条记录,但这是一个猜测),它应该是好的。您必须在特定的环境中进行测试

如果它在存储过程中,您可能希望包含类似于带有重新编译选项的
,以便。这会(稍微)增加每次运行的时间,但多次运行实际上会减少平均执行时间。此外,这允许数据库检查实际查询以及每次调用时不需要的部分

如果您直接创建SQL并传递它,那么我建议您将构建SQL的部分做得更智能一些,以便它只包含您实际需要的where子句的部分


您可能考虑的另一条路径是使用UNION ALL查询而不是可选参数。例如:

SELECT * FROM Teacher WHERE (TeacherId = @TeacherID)
UNION ALL
SELECT * FROM Teacher WHERE (@TeacherId = -1)
这实际上完成了完全相同的事情;但是,查询计划是可缓存的。我们在一些地方也使用了这种方法,并且看到了与使用重新编译相比的性能改进。我们不会在任何地方都这样做,因为我们的一些查询非常复杂,我宁愿受到性能的影响,也不愿让它们进一步复杂化

但最终,您需要进行大量测试



这里还有第二部分,你应该重新考虑<代码>选择*
。确保你只退回你真正需要的东西。跨网络边界移动数据非常昂贵,通常只需精确指定所需内容,即可获得相当数量的性能提升。此外,如果您需要的内容非常有限,您有时可以这样做,以便数据库引擎甚至不必接触底层表即可获得所需的数据。

如果
TeacherID
已编制索引,并且您正在将
-1
以外的值作为
TeacherID
传递以搜索特定教师的详细信息,则此查询最终将执行完整的表扫描,而不是搜索索引以检索特定教师的详细信息的可能更高效的选项


。。。除非您使用的是SQL 2008 SP1 CU5及更高版本,并使用
选项(重新编译)
提示。有关此主题的权威性文章,请参阅。

如果您真的担心性能,可以将过程分解为调用两个不同的过程:一个用于所有记录,另一个基于参数

If @TeacherID = -1
   exec proc_Get_All_Teachers
else
   exec proc_Get_Teacher_By_TeacherID @TeacherID
每一个都可以单独优化

这是你的系统,比较一下性能。考虑优化最流行的选择。如果大多数用户只选择一个记录,为什么隐藏他们的表现只是为了容纳少数选择所有教师的人(并且应该对表现有合理的期望)


我知道单个select查询更容易维护,但在某种程度上,维护的简单性最终会让位于性能。

George,你无法想象你的问题有多“热”。在一个问题中,您将“最佳实践”和“SQL”完美地结合在一起。添加了+1,如果可以的话会添加+100。我通常会按照@Jeff O的建议编写两个单独的查询。您可能还想阅读有关参数嗅探的内容。在这种情况下,动态SQL和重新编译可能更昂贵-我们只有两种不同的场景。您的
UNION-ALL
假设
TeacherId
永远不能为-1,所以我想知道,是否有可能以某种方式将其置于约束中,使SQL Server能够自行制定出一个好的计划?@hvd:很少有人会使用负数作为Id。如果您处于这种情况,那么您应该通过null并测试,而不是使用-1我知道,但我的观点是,SQL Server查询优化器没有为指向Erland工作的链接添加+1。这绝对是答案。对于一个简单的情况,如OP所显示的,这将是很好的。但是,如果可选搜索参数的数量超过1,则无法维护。例如,如果是2,则必须有4个s'procs…@ChrisLively-SQLServer2008将允许传递表值参数。proc中的select语句可以使用它,而不是单个值参数。