我有一个应用程序,其中用户有一个掩码,该掩码针对SQL Server 2008数据库运行sql语句。此外,用户可以在掩码中设置参数。考虑一个带有一个参数的面具,这是一个带有2个选项的下拉菜单:“Planes”和“Cars”。
当用户选择“Cars”并点击“Execute”按钮时,我在掩码中配置的以下SQL语句将命中数据库。
SELECT cars.id, cars.name
FROM cars
WHERE 'Cars' = 'Cars'
UNION ALL
SELECT planes.id, planes.name
FROM planes
WHERE 'Planes' = 'Cars'
(这是一个非常简单的例子,因为我的应用程序中的查询复杂得多,有很多JOINS等等......)
即使我将第二部分粘贴到SQL Server Management工作室,设置一些参数并点击执行,查询将需要几秒钟才能完成...结果为空。
我现在的问题:我如何优化第二部分,以便SQL Server认识到在第二个SELECT语句中,确实无事可做?
编辑:
我的第二个(“死”)查询执行一段时间的原因如下:在查询内部有JOINS,以及WHERE子句中的Sub-SELECT。我们说
SELECT planes.id, planes.name
FROM planes
INNER JOIN very_complex_colour_view colours
ON colours.id = planes.colour.id
WHERE 'Planes' = 'Cars'
事实上,甚至“飞机”表本身也是一个复杂的视图。
答案 0 :(得分:1)
根据参数,它从各个表中选择记录。
因此无需使用UNION ALL
。
使用IF ELSE
构造 -
DECLARE @Input VARCHAR(20) = 'Cars'
IF (@Input = 'Cars')
BEGIN
SELECT cars.id, cars.name
FROM cars
END
ELSE IF (@Input = 'Planes')
BEGIN
SELECT planes.id, planes.name
FROM planes
END
这也有助于SQL Optimizer使用Parameter Sniffing
技术并使用可提高查询性能的最佳执行计划。
更多关于Parameter Sniffing
-
答案 1 :(得分:0)
当我在我的系统上运行以下查询时:
select *
from <really big table that is not in the cache>
where 'planes' = 'cars'
结果在第一次及以后的时间内立即返回约1秒钟。
我怀疑你的实际查询比这个例子更复杂。而且,简化就是消除了这个问题。即使我尝试使用连接进行上述操作,基本上也没有性能损失。
根据我看到的执行计划,SQL Server认识到常量始终为false。以下查询:
select *
from Published_prev2..table1 sv join
Published_prev2..table2 sl
on sv.id= sl.id
where 'planes' = 'cars'
为执行计划生成持续扫描。使用“cars
= cars
”的相同查询会生成一个更复杂的计划,该计划具有连接等等。