Waktu pengujian
Anda tidak melihat evaluasi fungsi individual per baris di EXPLAIN
keluaran.
Uji dengan EXPLAIN ANALYZE
untuk mendapatkan waktu kueri aktual untuk membandingkan efektivitas keseluruhan. Jalankan beberapa kali untuk mengesampingkan artefak caching. Untuk kueri sederhana seperti ini, Anda mendapatkan angka yang lebih andal untuk total waktu proses dengan:
EXPLAIN (ANALYZE, TIMING OFF) SELECT ...
Membutuhkan Postgres 9.2+ . Per dokumentasi :
Mencegah evaluasi berulang
Biasanya, ekspresi dalam subkueri dievaluasi sekali . Tetapi Postgres dapat menciutkan subkueri sepele jika dianggap lebih cepat.
Untuk memperkenalkan penghalang pengoptimalan, Anda dapat menggunakan CTE
alih-alih subquery. Ini menjamin bahwa Postgres menghitung ST_SnapToGrid(geom, 50)
hanya sekali:
WITH cte AS (
SELECT ST_SnapToGrid(geom, 50) AS geom1
FROM points
)
SELECT COUNT(*) AS n
, ST_X(geom1) AS x
, ST_Y(geom1) AS y
FROM cte
GROUP BY geom1; -- see below
Namun, ini mungkin lebih lambat daripada subquery karena lebih banyak overhead untuk CTE. Panggilan fungsi mungkin sangat murah. Secara umum, Postgres lebih tahu cara mengoptimalkan rencana kueri. Hanya perkenalkan penghalang pengoptimalan seperti itu jika Anda tahu lebih baik.
Sederhanakan
Saya mengubah nama titik yang dihitung di subquery / CTE menjadi geom1
untuk memperjelas itu berbeda dari geom
asli . Itu membantu memperjelas hal yang lebih penting hal di sini:
GROUP BY geom1
bukannya:
GROUP BY x, y
Itu jelas lebih murah - dan mungkin memengaruhi apakah panggilan fungsi diulang. Jadi, ini mungkin yang tercepat:
SELECT COUNT(*) AS n
, ST_X(ST_SnapToGrid(geom, 50)) AS x
, ST_y(ST_SnapToGrid(geom, 50)) AS y
FROM points
GROUP BY ST_SnapToGrid(geom, 50); -- same here!
Atau mungkin ini:
SELECT COUNT(*) AS n
, ST_X(geom1) AS x
, ST_y(geom1) AS y
FROM (
SELECT ST_SnapToGrid(geom, 50) AS geom1
FROM points
) AS tmp
GROUP BY geom1;
Uji ketiganya dengan EXPLAIN ANALYZE
atau EXPLAIN (ANALYZE, TIMING OFF)
dan lihat sendiri. Menguji>> menebak.