哪两个查询更有效?

时间:2012-03-27 17:06:51

标签: sql select sql-server-2005

我有以下两个查询,我相信使用三个索引扫描(第二个)而不是一个完整的查询更有效但我需要更多的意见。另外,如何从第二个查询中的三个计数中获得一个计数?我怎样才能将它们组合成一个?

第一次查询

SELECT count(*) FROM bldng 
WHERE (bldng_type LIKE '%PTR%' OR bldng_type LIKE '%FACILITY-A%' 
OR bldng_type LIKE '%FACILITY-B%') AND area_sqf > 500

第二次查询

SELECT count(*) FROM bldng WHERE bldng_type LIKE '%PTR%' AND area_sqf > 500 
UNION ALL
SELECT count(*) FROM bldng WHERE bldng_type LIKE '%FACILITY-A%' AND area_sqf > 500  
UNION ALL
SELECT count(*) FROM bldng WHERE bldng_type LIKE '%FACILITY-B%' AND area_sqf > 500

好的,这是我在使用'set statistics io on'

运行两个查询后得出的结果

第一(单行)查询:

Category    Timestamp   Duration    Message Line    Position
Connection  3/27/2012 2:36:49 PM        3615: Table 'bldng'. Scan count 1, logical  reads 33320, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.   1   0

第二次查询:

Category    Timestamp   Duration    Message Line    Position
Connection  3/27/2012 2:38:15 PM        3615: Table 'bldng'. Scan count 15, logical reads 76703, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.   1   0

Category    Timestamp   Duration    Message Line    Position
Connection  3/27/2012 2:38:15 PM        3615: 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.    1   0

我不知道如何解释这些。我是否比较逻辑读取33320< 76703?所以第一个没那么意味着它运行效率更高?

3 个答案:

答案 0 :(得分:2)

首先,您编写的所有语句均未使用bldng_type列上的任何索引。 <{1}}与字符串开头的通配符进行比较是不可优化的。

在这种情况下,我猜第一个查询更有效,因为它涉及单个表扫描而不是三个独立的查询。但请参见下文。

“哪个查询更有效”的问题只能通过检查数据库引擎生成的查询计划来回答。该计划不仅取决于查询的结构,还取决于您收集的有关您所比较的列的统计信息,并且由于这些统计信息可能会随着您在数据库中插入和更新数据而发生变化,因此最有效的查询计划可能会随时间而变化同样。

最后,“完美”的数据库引擎会将所有语义相同的查询减少到相同的优化查询计划。在您引用的情况下,这是不可能的,因为查询实际上会产生不同的结果。但是如果你把查询写成可识别的相同,那么它们应该(再次,在一个完美的数据库引擎中)在相同的时间内运行。

答案 1 :(得分:0)

运行一个语句通常比运行三个语句更有效,然后将结果联合起来。

我假设您想要提供所有过滤器的总计数,(将第二个查询的3行与第一个查询中的总计相加)。

当你说“使用3个索引”时 - 你是否在bldng_type列上构建了3个不同的索引?

我会坚持使用第一个语句,因为通常它只使用所有3个过滤器对bldng_type列的索引执行过滤,对area_sqf列进行过滤,然后对过滤器的结果进行计数。

如果你运行第二个,它可能会尝试查询表3次,然后将结果连接在一起。

但是要确定,您需要查看查询的执行计划以确定它在做什么。

答案 2 :(得分:0)

不是SQL专家,但从我记忆中来看,单个语句通常更好,因为它允许优化器更好地完成工作。虽然不能保证短路布尔逻辑,但它是第一个语句中优化器可用的选项,而在第二个选项中,您明确地避免使用它。此外,您可能希望通过将它们与括号分组来优先化OR比较...