Saya baru saja meninjau beberapa kode lama yang ditulis untuk pra-8.4 PostgreSQL , dan saya melihat sesuatu yang sangat bagus. Saya ingat memiliki fungsi khusus melakukan beberapa hal ini pada hari itu, tapi saya lupaarray_agg()
. Untuk ulasan, agregasi modern ditulis seperti ini.
SELECT array_agg(x ORDER BY x DESC) FROM foobar;
Namun, pada suatu waktu, ditulis seperti ini,
SELECT ARRAY(SELECT x FROM foobar ORDER BY x DESC);
Jadi, saya mencobanya dengan beberapa data uji ..
CREATE TEMP TABLE foobar AS
SELECT * FROM generate_series(1,1e7)
AS t(x);
Hasilnya mengejutkan .. Cara #OldSchoolCool jauh lebih cepat: kecepatan 25%. Apalagi menyederhanakannya tanpa ORDER, menunjukkan kelambatan yang sama.
# EXPLAIN ANALYZE SELECT ARRAY(SELECT x FROM foobar);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
Result (cost=104425.28..104425.29 rows=1 width=0) (actual time=1665.948..1665.949 rows=1 loops=1)
InitPlan 1 (returns $0)
-> Seq Scan on foobar (cost=0.00..104425.28 rows=6017728 width=32) (actual time=0.032..716.793 rows=10000000 loops=1)
Planning time: 0.068 ms
Execution time: 1671.482 ms
(5 rows)
test=# EXPLAIN ANALYZE SELECT array_agg(x) FROM foobar;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=119469.60..119469.61 rows=1 width=32) (actual time=2155.154..2155.154 rows=1 loops=1)
-> Seq Scan on foobar (cost=0.00..104425.28 rows=6017728 width=32) (actual time=0.031..717.831 rows=10000000 loops=1)
Planning time: 0.054 ms
Execution time: 2174.753 ms
(4 rows)
Jadi, apa yang terjadi di sini. Mengapa array_agg , fungsi internal jauh lebih lambat dari voodoo SQL perencana?
Menggunakan " PostgreSQL 9.5.5 pada x86_64-pc-linux-gnu, dikompilasi oleh gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005, 64-bit"
array_agg
harus melacak urutan inputnya di manaARRAY
konstruktor tampaknya melakukan sesuatu yang kira-kira setara denganUNION
sebagai ekspresi internal. Jika saya harus berani menebak,array_agg
kemungkinan akan membutuhkan lebih banyak memori. Saya tidak bisa menguji ini secara mendalam tetapi pada PostgreSQL 9.6 berjalan pada Ubuntu 16.04ARRAY()
kueri denganORDER BY
menggunakan penggabungan eksternal dan lebih lambat dariarray_agg
kueri. Seperti yang Anda katakan, singkat membaca kode jawaban Anda adalah penjelasan terbaik yang kami miliki.