1

我有一个应用程序,其中用户有一个掩码,可以针对 SQL Server 2008 数据库运行 sql 语句。此外,用户可以在掩码中设置参数。考虑一个带有一个参数的掩码,它是一个带有 2 个选项的下拉菜单:“飞机”和“汽车”。

当用户选择“汽车”并点击“执行”按钮时,我之前在掩码中配置的以下 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 Studio 中,设置一些参数并点击执行,查询也需要几秒钟才能完成......结果为空。

我现在的问题是:如何优化第二部分,以便 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' 

事实上,即使是“planes”表本身也是一个复杂的视图。

4

2 回答 2

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-

于 2013-06-06T14:20:41.163 回答
0

当我在我的系统上运行以下查询时:

select *
from <really big table that is not in the cache>
where 'planes' = 'cars'

结果在第一次大约 1 秒内返回,随后立即返回。

我怀疑你的实际查询比这个例子更复杂。而且,简化正在消除问题。即使我通过连接尝试上述方法,基本上也不会影响性能。

根据我看到的执行计划,SQL Server 认识到该常量始终为假。以下查询:

select *
from Published_prev2..table1 sv join
     Published_prev2..table2 sl
     on sv.id= sl.id
where 'planes' = 'cars'

生成执行计划的持续扫描。cars使用 ' = '的相同查询cars会产生一个更复杂的计划,其中包含连接等。

于 2013-06-06T14:28:52.530 回答