计算 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 或者(我相信)如果您 运行 使用列作为谓词进行搜索,它会自动创建
是否有任何数据库引擎允许您 运行 一个 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 或者(我相信)如果您 运行 使用列作为谓词进行搜索,它会自动创建