PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Hapus menggunakan CTE lebih lambat daripada menggunakan tabel temp di Postgres

CTE lebih lambat karena harus dijalankan tanpa perubahan (melalui pemindaian CTE).

TFM (bagian 7.8.2) menyatakan: Pernyataan modifikasi data di WITH dieksekusi tepat sekali, dan selalu sampai selesai, terlepas dari apakah kueri utama membaca semua (atau memang ada) keluarannya. Perhatikan bahwa ini berbeda dari aturan untuk SELECT di WITH:seperti yang dinyatakan di bagian sebelumnya, eksekusi SELECT adalah dilakukan hanya sejauh permintaan utama meminta outputnya.

Dengan demikian, ini merupakan penghalang pengoptimalan; untuk pengoptimal, pembongkaran CTE tidak diperbolehkan, meskipun itu akan menghasilkan rencana yang lebih cerdas dengan hasil yang sama.

Solusi CTE dapat difaktorkan ulang menjadi subquery yang digabungkan (mirip dengan tabel temp dalam pertanyaan). Di postgres, subquery yang digabungkan biasanya lebih cepat daripada varian EXISTS() saat ini.

DELETE FROM customer del
USING ( SELECT id
        , row_number() over(partition by uuid order by created_date desc)
                 as rn
        FROM customer
        ) sub
WHERE sub.id = del.id
AND sub.rn > 1
        ;

Cara lain adalah dengan menggunakan TEMP VIEW . Ini secara sintaksis setara dengan temp table kasus, tapi secara semantik setara dengan formulir subkueri gabungan (mereka menghasilkan tepat rencana kueri yang sama, setidaknya dalam kasus ini). Ini karena pengoptimal Postgres membongkar tampilan dan menggabungkannya dengan kueri utama (pull-up ). Anda dapat melihat view sebagai semacam makro di PG.

CREATE TEMP VIEW targets
AS SELECT id
        , row_number() over(partition by uuid ORDER BY created_date DESC) AS rn
FROM customer;

EXPLAIN
DELETE FROM customer
WHERE id IN ( SELECT id
            FROM targets
            WHERE rn > 1
        );

[DIPERBARUI:Saya salah tentang CTE yang harus selalu dieksekusi hingga selesai, yang hanya berlaku untuk CTE yang memodifikasi data]



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menghitung baris terkait termasuk subkategori?

  2. Buat daftar batasan untuk semua tabel dengan pemilik berbeda di PostgreSQL

  3. Array PHP ke array postgres

  4. Kolom fungsi jendela Postgres dengan Rails

  5. Menghitung Biaya Rata-Rata Tertimbang dari stok produk