2014-02-08 57 views
0

我试图测量查询的执行时间,但我有一种感觉,我的结果是错误的。执行时间select * vs select count(*)

之前每个查询我执行: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的专用服务器

谢谢!

+1

'count(*)'返回的信息较少。大多数关系型数据库不得不为较少的信息做更少的工作。它使用查询计划以最少的工作量提供所需的信息。 – usr

+0

出于实用目的,选择count(*)将更快,因为它只向调用数据的应用程序返回一行。 –

+0

@DanBracuk如果您正在测量客户端的执行时间,并且没有通过计时直到* first *行返回,而是解释分析报告*服务器端*执行时间来纠正该错误,则为真。 –

回答

2

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

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

+0

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

+1

日志中没有时间不包含客户端处理。而某些大型数据集的客户端处理可能需要一段时间(主要是客户端过载时)。这取决于客户端处理的复杂性。简单..对于COPY输出需要零时间,很多对齐的复杂(如表格)会很慢。 –

0

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

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

+1

只适用于新版本(来自PostgreSQL 9.2) –

+0

唯一的索引位于主键上。有什么方法可以查看索引是否被使用? – user3245803

+1

EXPLAIN SELECT ..全部显示 –

0

选择* =选择所有数据的所有列包括 SELECT COUNT(*)=计数有多少行 例如该表

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

SELECT *将显示所有表

SELECT COUNT( *)将显示总行数= 4

+0

我不认为OP什么是知道查询之间的区别是什么,但为什么他们有这样不同的表现 –

+0

输出所有我需要的数据。 4分钟(不是32秒,如服务器日志所示),但这是客户的测量。我需要知道为什么服务器的日志有这样的差异。它是否也包含输出操作? – user3245803