PostgreSQL中最有效的数组表示法

时间:2018-05-14 00:00:20

标签: postgresql

使用数组作为常量,效率更高:

array[1,2,3]

'{1,2,3}'::int[]`

或者,更复杂:

array['1812-01-01'::date, '1812-02-02'] 

'{1812-01-01,1812-02-02}'::date[]

尽管事实很棒,但我真的很害怕PostgreSQL的消息来源。

更新

部分答案,基于@VaoTsun提供的调查(非常感谢!)令人惊讶'{1,2,3}'::int[]array[1,2,3]更快。迪西!

1 个答案:

答案 0 :(得分:1)

在我的机器上array[]总是比'{}'一个慢一点:

so=# do $$
declare
 t text;
 ts timestamptz;
begin
 for n in 1..10 loop
  select clock_timestamp() into ts;
  for i in 1..99999 loop
   execute format($f$select array['18%s-01-01'::date, '18%s-02-02']$f$,i,i) into t;
  end loop;
  raise info '%', t||' "[" '||clock_timestamp() - ts;

  select clock_timestamp() into ts;
  for i in 1..99999 loop
   execute format($f$select '{18%s-01-01,18%s-02-02}'::date[]$f$,i,i) into t;
  end loop;
  raise info '%', t||' "{" '||clock_timestamp() - ts;
 end loop;
end; $$;
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:01.99259
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.691473
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:02.207583
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.762358
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:01.926091
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.685358
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:01.98542
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.686831
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:02.01972
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.698365
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:02.008609
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.698494
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:01.987951
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.698711
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:01.977347
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.707921
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:01.945438
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.663771
INFO:  {1899999-01-01,1899999-02-02} "[" 00:00:02.079186
INFO:  {1899999-01-01,1899999-02-02} "{" 00:00:01.752366
DO
Time: 37178.056 ms

隐含的文档表明"卷曲"在第一行引入数组的方法:

https://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-INPUT

  

要将数组值写为文字常量,请将该元素括起来   花括号内的值并用逗号分隔。

后来: https://www.postgresql.org/docs/current/static/sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS

  

数组构造函数是一个使用构建数组值的表达式   其成员要素的价值。

因此,您可以期望从数组构造中构建卷曲值以进行额外的滴答。但我当然只是在猜测。答案仅仅是为了测量两种方式在无负载PC上及时混合的线性影响......

同样IN (scalar list)被重写为= ANY(array)构造在"卷曲"格式:

so=# explain analyse select * from pg_database where datname in ('t','so');
                                              QUERY PLAN
-------------------------------------------------------------------------------------------------------
 Seq Scan on pg_database  (cost=0.00..1.02 rows=2 width=254) (actual time=0.105..0.109 rows=2 loops=1)
   Filter: (datname = ANY ('{t,so}'::name[]))

我并不是说这样做是一种暗示,但它看起来是内部选择的方式而不是array[构造,所以可能是一个暗示