我有一个存储过程,它使用相同的列,但具有不同的WHERE
子句。
像这样的东西。
SELECT
alarms.startt, alarms.endt, clients.code, clients.Plant,
alarms.controller, alarmtype.atype, alarmstatus.[text]
FROM alarms
INNER JOIN clients ON alarms.clientid = clients.C_id
INNER JOIN alarmstatus ON alarms.statusid = alarmstatus.AS_id
INNER JOIN alarmtype ON alarms.typeid = alarmtype.AT_id
我在3 if if(条件)中放入相同的查询,其中WHERE
子句根据变量中传递的参数而变化。
我是否必须在每个if?
中为每个条件反复编写整个字符串或者我可以优化它一次,唯一会改变的是WHERE子句吗?
答案 0 :(得分:2)
你不必这样做,你可以通过做
这样的事情来绕过它SELECT *
FROM [Query]
WHERE (@Parameter = 1 AND Column1 = 8)
OR (@Parameter = 2 AND Column2 = 8)
OR (@Parameter = 3 AND Column3 = 8)
然而,仅仅因为你可以做某事,并不意味着你应该做。较不详细的SQL并不意味着更好的性能,因此请使用以下内容:
IF @Parameter = 1
BEGIN
SELECT *
FROM [Query]
WHERE Column1 = 8
END
ELSE IF @Parameter = 2
BEGIN
SELECT *
FROM [Query]
WHERE Column2 = 8
END
ELSE IF @Parameter = 3
BEGIN
SELECT *
FROM [Query]
WHERE Column3 = 8
END
虽然与第一个查询相当,但应该会产生更好的性能,因为它会更好地进行优化。
答案 1 :(得分:2)
如果您执行以下操作,则可以避免重复代码:
WHERE (col1 = @var1 AND @var1 IS NOT NULL)
OR ...
OPTION RECOMPILE;
您还可以通过数据库的参数化设置(简单与强制)对此行为产生一些影响。
由于参数嗅探而避免重复代码并避免次优计划的事情是使用动态SQL:
DECLARE @sql NVARCHAR(MAX) = N'SELECT ...';
IF @var1 IS NOT NULL
SET @sql = @sql + ' WHERE ...';
如果您启用了“针对即席查询优化”的服务器设置,这可能会更好。
答案 2 :(得分:1)
我可能会坚持重复整个SQL语句,但过去已经采用了这个...
WHERE (@whichwhere=1 AND mytable.field1=@id)
OR (@whichwhere=2 AND mytable.field2=@id)
OR (@whichwhere=3 AND mytable.field3=@id)
不是特别易读,如果执行计划很慢,你必须检查执行计划,但它会阻止你重复代码。
答案 3 :(得分:1)
因为没有人提出这个建议。您可以将原始查询放在视图中,然后使用不同的WHERE子句访问该视图。
为了提高性能,如果您知道WHERE子句中常用的列,则甚至可以向视图添加索引(请查看http://msdn.microsoft.com/en-us/library/dd171921(v=sql.100).aspx)。
答案 4 :(得分:0)
与SQL中的大多数事情一样:它取决于。这里有一些考虑因素。
一种方法是将不同的procs执行到临时表中。然后每个proc都有自己的查询计划。
另一种方法是使用动态SQL,再次为每个“查询”分配自己的计划。
第三个方法是编写一个为每个选项生成SQL的应用程序,这可以是存储过程或sql字符串。
然后有一个数据集并针对它进行测试驱动开发(对于每种方法都是如此)。
最终,最好的学习解决方案可能是 a)阅读SQL Kalen Delaney Inside SQL是一位公认的专家。 b)根据您自己的数据测试您自己的解决方案
答案 5 :(得分:0)
我会这样: 在哪里8 = CASE @parameter 当1那么Column1 当2那么Column2 。 。