计算 SQL 语句中返回的行数

Count number of rows returned in a SQL statement

是否有任何数据库引擎允许您 运行 一个 EXPLAIN (或其他函数),它会给您一个大概的值计数,这些值可能是 return 之前编辑的聚合是 运行(不是扫描的行,但实际上是 returned)?例如,在以下查询中:

SELECT gender, COUNT(1) FROM sales JOIN (
       SELECT id, person FROM sales2 WHERE country='US'
       GROUP BY person_id
) USING (id)
WHERE sales.age > 20
GROUP BY gender

假设此查询在聚合后 returns 3 行,但如果未聚合则将 return 170M 行。

是否有任何工具可以让您 运行 查询以获得这个“170M”数字,或者这是否与复杂性理论(或类似的东西)有关,它几乎与 运行 查询(没有最后的 aggregation/having/sort/limit/etc)来获取计数?换句话说,重写为:

SELECT COUNT(1) FROM sales JOIN (
       SELECT id, person FROM sales2 WHERE country='US'
       GROUP BY person_id
) USING (id)
WHERE sales.age > 20

但仍然必须执行查询。

作为使用当前 (mysql) 的示例,说明如何 'off' 获得我正在寻找的内容:

explain select * from movies where title>'a';
# rows=147900
select count(1) from _tracktitle where title>'a';
# 144647 --> OK, pretty close


explain select * from movies where title>'u';
# rows=147900
select * from movies where title>'u';
# 11816 --> Not close at all

MS Sql 服务器提供“执行计划”。在下图中,我有疑问,我按 (Ctrl-L) 查看计划。

在我的查询中,我 return 首先使用所有记录,然后使用相同的 table。

查看与红色箭头对应的指标 - 估计查询为 运行 时将扫描的行数。在这种情况下,无论是 count(*) 还是 *,这个数字都是相同的,以防万一!

假设您可以使用 MS SQL 服务器,您可以利用优化器用于基数估计的相同数据:DBCC SHOW_STATISTICS (table, index) WITH HISTOGRAM

您返回的部分数据集是每列直方图,它实质上是 table.

中每个值范围的行数

您可能想以编程方式查询数据,实现此目的的一种方法是将其插入临时文件 table:

CREATE TABLE #histogram (
    RANGE_HI_KEY datetime PRIMARY KEY,
    RANGE_ROWS INT,
    EQ_ROWS INT,
    DISTINCT_RANGE_ROWS INT,
    AVG_RANGE_ROWS FLOAT
)

INSERT INTO #histogram 
EXEC ('DBCC SHOW_STATISTICS (Users, CreationDate) WITH HISTOGRAM')

SELECT 'Estimate', SUM(RANGE_ROWS+EQ_ROWS) FROM #histogram WHERE RANGE_HI_KEY BETWEEN '2010-08-30 08:28:45.070' AND '2010-09-20 22:15:33.603'
UNION ALL
select 'Actual', COUNT(1) from Users u WHERE u.CreationDate BETWEEN '2010-08-30 08:28:45.070' AND '2010-09-20 22:15:33.603'

例如,检查 运行 针对 Stack Overflow Database.

的相同查询
| -------- | ----- |
| Estimate | 98092 |
| Actual   | 11715 |

看起来很多,但请记住整个 table 有将近 1500 万条记录。

关于精度和其他问题的说明

  • 直方图步骤的最大数量上限为 200 - 这不是很多,因此您无法保证 10% 的误差范围,但 SQL 服务器也不会。
  • 当您将数据插入 table 时,直方图可能会变得陈旧,因此您的结果会更加偏斜。
  • update this data 有不同的方法,有些方法相当快,而另一些方法实际上需要完整 table 扫描
  • 并非所有列都有统计信息。您可以 create it manually 或者(我相信)如果您 运行 使用列作为谓词进行搜索,它会自动创建