为什么 SELECT * 比按名称选择所有列(以不同的列顺序)要快得多?

Evg*_*eny 12 postgresql postgresql-9.2

在包含 a、b、c、d、e、f、g、h、i、j、k 列的表上,我得到:

select * from misty order by a limit 25;
Time: 302.068 ms
Run Code Online (Sandbox Code Playgroud)

和:

select c,b,j,k,a,d,i,g,f,e,h from misty order by a limit 25;
Time: 1258.451 ms
Run Code Online (Sandbox Code Playgroud)

有没有办法让按列选择的速度一样快?

更新:

表上没有索引,新创建的

这是解释分析,似乎没有太大帮助:

explain analyze select * from misty order by a limit 25;

Limit  (cost=43994.40..43994.46 rows=25 width=190) (actual time=404.958..404.971 rows=25 loops=1)
->  Sort  (cost=43994.40..45731.11 rows=694686 width=190) (actual time=404.957..404.963 rows=25 loops=1)
     Sort Key: a
     Sort Method: top-N heapsort  Memory: 28kB
     ->  Seq Scan on misty  (cost=0.00..24390.86 rows=694686 width=190) (actual time=0.013..170.945 rows=694686 loops=1)
Total runtime: 405.019 ms
(6 rows)
Run Code Online (Sandbox Code Playgroud)

和:

explain analyze select c,b,j,k,a,d,i,g,f,e,h from misty order by a limit 25;

Limit  (cost=43994.40..43994.46 rows=25 width=190) (actual time=1371.735..1371.745 rows=25 loops=1)
->  Sort  (cost=43994.40..45731.11 rows=694686 width=190) (actual time=1371.733..1371.736 rows=25 loops=1)
     Sort Key: a
     Sort Method: top-N heapsort  Memory: 28kB
     ->  Seq Scan on misty  (cost=0.00..24390.86 rows=694686 width=190) (actual time=0.015..516.355 rows=694686 loops=1)
Total runtime: 1371.797 ms
(6 rows)
Run Code Online (Sandbox Code Playgroud)

ami*_*lan 12

这被发布到 pgsql-hackers 邮件列表,我试图在那里简要回答。似乎如果目标列表(指定的列)与关系的元组描述符完全匹配,即在列数和顺序方面,那么底层扫描可以返回一个元组,该元组可以由封闭的 Sort 节点直接使用。另一方面,如果目标列表不匹配(按顺序或指定列的数量),则扫描返回一种元组形式,需要 Sort 的数据准备步骤执行额外的工作(从内部元组格式转换为排序码直接消耗的格式)。

顺便说一下,'*' 在内部被转换成一个(直观地)匹配关系的元组描述符的列表。

编辑:如果您查看后者的 EXPLAIN ANALYZE 的 Seq Scan 的实际时间,您会发现它比前者的要多。这是因为扫描执行了额外的投影步骤(即将堆元组转换为内部 values[], nulls[] 格式)。由于这种情况发生,上层 Sort 节点必须在其数据初始化中做额外的工作,将其转换回实际排序步骤理解的元组格式。这可以从 Sort 的启动成本中看出。在前一种情况下不会发生这种情况。也就是说,扫描按原样返回元组,排序的初始化步骤只是简单地复制它。

  • 亲爱的先生,如果我只需要一些列而不是全部,哪个会更快?选择 * 或选择 some_of_columns?多谢。 (2认同)