执行时间选择* vs选择计数(*)

时间:2014-02-08 13:27:13

标签: sql database postgresql time

我正在尝试测量查询的执行时间,但我觉得我的结果是错误的。

在执行每个查询之前:sync; echo 3 > /proc/sys/vm/drop_caches

我的服务器日志文件结果是:

2014-02-08 14:28:30 EET LOG:  duration: 32466.103 ms  statement: select * from partsupp
2014-02-08 14:32:48 EET LOG:  duration: 9785.503 ms   statement: select count(*) from partsupp

不应该select count(*)执行更多时间,因为它会进行更多操作吗?

要输出select *的所有结果,我需要4分钟(不是32秒,如服务器日志所示)。我知道客户端必须输出大量数据并且速度很慢,但是服务器的日志呢?它是否也计算输出操作?

我还使用了explain analyze,结果是(正如预期的那样):

select *:        Total runtime: 13254.733 ms
select count(*): Total runtime: 13463.294 ms

我已多次运行,结果相似。

日志到底测量的是什么?

为什么在select *和服务器日志之间的explain analyze查询中存在如此大的差异,尽管它不计算I / O操作?

日志测量解释分析之间有什么区别?

我有一个使用Ubuntu 12.04和PostgreSQL 9.1的专用服务器

谢谢!

3 个答案:

答案 0 :(得分:2)

任何聚合函数都有一些小的开销 - 但是在第二方面SELECT *根据列号和列大小发送给客户端大量的数据。

日志测量是一个总查询时间,它可以类似于EXPLAIN ANALYZE - 但是更多的时间明显更快,因为EXPLAIN ANALYZE为执行计划的所有子节点收集执行时间(和执行统计信息)。而且通常是很重要的开销。但是从服务器到客户端的传输数据没有任何开销。

答案 1 :(得分:0)

第一个查询要求表中的所有行。因此,必须阅读整个表格。

第二个查询只询问有多少行。数据库可以通过读取整个表来回答这个问题,但也可以通过读取它对该表的任何索引来回答这个问题。由于索引小于表,所以这样做会更快。实际上,几乎所有表都有索引(因为主键约束也会创建索引)。

答案 2 :(得分:0)

选择* =选择包含所有列的所有数据 select count(*)= count行数 例如这个表

------------------------
name | id | address 
----------------------
s    | 12 | abc
---------------------  
x    | 14 | cc
---------------------  
y    | 15 | vv
---------------------  
z   | 16 | ll
---------------------  

select *将显示所有表格

select count(*)将显示行的总数= 4