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_aggharus melacak urutan inputnya di manaARRAYkonstruktor tampaknya melakukan sesuatu yang kira-kira setara denganUNIONsebagai ekspresi internal. Jika saya harus berani menebak,array_aggkemungkinan akan membutuhkan lebih banyak memori. Saya tidak bisa menguji ini secara mendalam tetapi pada PostgreSQL 9.6 berjalan pada Ubuntu 16.04ARRAY()kueri denganORDER BYmenggunakan penggabungan eksternal dan lebih lambat dariarray_aggkueri. Seperti yang Anda katakan, singkat membaca kode jawaban Anda adalah penjelasan terbaik yang kami miliki.