伯爵(*)真的很贵吗?

Ani*_*mde 18 asp.net performance sql-server-2005 premature-optimization

我有一个页面,其中有4个选项卡,根据不同的表格显示4个不同的报告.

我使用select count(*) from <table>查询获取每个表的行数,并在选项卡上显示每个表中可用的行数.结果,每个页面回发导致count(*)执行5个查询(4个用于获取计数,1个用于分页)和1个用于获取报告内容的查询.

现在我的问题是:count(*)查询真的很贵 - 我应该在页面的视图状态中保留行计数(至少显示在选项卡上的那些)而不是多次查询吗?

COUNT(*)查询的费用是多少?

Qua*_*noi 8

通常,成本COUNT(*)成本与满足查询条件的记录数加上准备这些记录所需的时间(取决于基础查询复杂性)成比例.

在您处理单个表的简单情况下,通常会进行特定的优化以使此类操作变得便宜.例如,在COUNT(*)没有WHERE条件的情况下从单个MyISAM表中执行MySQL- 这是瞬时的,因为它存储在元数据中.

例如,让我们考虑两个查询:

SELECT  COUNT(*)
FROM    largeTableA a
Run Code Online (Sandbox Code Playgroud)

由于每条记录都满足查询,因此COUNT(*)成本与表中记录的数量成正比(即与返回的记录成比例)(假设它需要访问行并且没有特定的优化来处理它)

SELECT  COUNT(*)
FROM    largeTableA a
JOIN    largeTableB b
ON      a.id = b.id
Run Code Online (Sandbox Code Playgroud)

在这种情况下,引擎很可能会使用HASH JOIN,执行计划将是这样的:

  1. 在较小的表上构建哈希表
  2. 扫描较大的表,查找哈希表中的每个记录
  3. 随时计算比赛数.

在这种情况下,COUNT(*)开销(步骤3)将是可以忽略的,并且查询时间将完全由步骤1和2定义,即构建哈希表并查找它.对于这样的查询,时间将是O(a + b):它实际上并不取决于匹配的数量.

然而,如果有索引在两个a.idb.id,则MERGE JOIN可以选择和COUNT(*)时间将正比于匹配的数量再次,由于一个索引查找每个匹配之后将被执行.


Rub*_*ink 8

您需要附加SQL事件探查器类似L2SProf的应用程序级别分析器,并在以下情况下查看上下文中的实际查询成本:

  • 猜测问题是什么,并试图确定潜在解决方案的可能好处

  • 允许其他人在da interwebs上猜你 - 有很多错误的信息没有引用,包括在这个帖子中(但不在这篇文章中:P)

当你这样做时,最清楚的是最好的方法是什么 - 即,SELECT COUNT是否支配着什么,等等.

完成后,您还将知道您选择做出的任何更改是否产生了积极或消极的影响.