【问题标题】:Which query of the two is more efficient?两者中哪个查询效率更高?
【发布时间】:2012-04-11 06:21:32
【问题描述】:

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

第一次查询

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

【问题讨论】:

  • 您使用的是什么 DBMS?您是否查看过每个查询的执行计划?
  • 此外,这些查询做了两件不同的事情。您是否尝试获取符合所有条件的记录数?
  • 是的,对不起,纠正了第一个错误。添加了“计数”
  • @dido 他们仍然是 2 个不同的结果集。你是不是也想把GROUP BY bldng_type加到第一个?
  • 嗯,但是当我执行这两个语句时,它们似乎给了我相同的结果。你能详细说明有什么区别吗?不,我并不是要“分组”。但是你为什么问?这有帮助吗?你认为我为什么需要它?

标签: sql select sql-server-2005


【解决方案1】:

首先,您编写的所有语句都没有使用bldng_type 列上的任何索引。 LIKE 与字符串开头的通配符的比较是不可优化的。

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

    【讨论】:

    • 好吧,当我运行这两个语句时,似乎第一个语句的执行速度总是比第二个语句慢(比较运行它们所需的时间)。不知道你说的执行计划是什么意思?我只是为一个新项目写这些。还没有真正开发出其他任何东西......关于执行所需时间的信息(来自我正在使用的编辑器)是否可靠?
    【解决方案3】:

    不是 SQL 专家,但据我所知,单个语句通常更好,因为它可以让优化器更好地完成工作。尽管不能保证短路布尔逻辑,但它是优化器在第一个语句中可用的选项,而在第二个选项中,您明确避免它。此外,您可能希望通过用括号将它们分组来确定 OR 比较的优先级...

    【讨论】:

      猜你喜欢
      • 2011-05-23
      • 2013-03-30
      • 2011-03-09
      • 2015-03-14
      • 1970-01-01
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      • 2020-06-18
      相关资源
      最近更新 更多