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

PostgreSQL:Bagaimana cara mengetahui angka yang hilang dalam kolom menggunakan generate_series()?

Data sampel yang diberikan:

create table results ( commandid integer primary key);
insert into results (commandid) select * from generate_series(1,1000);
delete from results where random() < 0.20;

Ini berfungsi:

SELECT s.i AS missing_cmd
FROM generate_series(0,1000) s(i)
WHERE NOT EXISTS (SELECT 1 FROM results WHERE commandid = s.i);

seperti halnya formulasi alternatif ini:

SELECT s.i AS missing_cmd
FROM generate_series(0,1000) s(i)
LEFT OUTER JOIN results ON (results.commandid = s.i) 
WHERE results.commandid IS NULL;

Kedua hal di atas tampaknya menghasilkan rencana kueri yang identik dalam pengujian saya, tetapi Anda harus membandingkan dengan data Anda di database menggunakan EXPLAIN ANALYZE untuk melihat mana yang terbaik.

Penjelasan

Perhatikan bahwa alih-alih NOT IN Saya telah menggunakan NOT EXISTS dengan subquery dalam satu formulasi, dan OUTER JOIN biasa di lain. Jauh lebih mudah bagi server DB untuk mengoptimalkan ini dan menghindari masalah membingungkan yang dapat muncul dengan NULL s di NOT IN .

Saya awalnya menyukai OUTER JOIN formulasi, tetapi setidaknya dalam 9.1 dengan data pengujian saya NOT EXISTS formulir dioptimalkan untuk rencana yang sama.

Keduanya akan berkinerja lebih baik daripada NOT IN formulasi di bawah ini ketika seri besar, seperti dalam kasus Anda. NOT IN digunakan untuk meminta Pg untuk melakukan pencarian linier dari IN list untuk setiap tuple yang sedang diuji, tetapi pemeriksaan rencana kueri menunjukkan bahwa Pg mungkin cukup pintar untuk melakukan hashing sekarang. NOT EXISTS (diubah menjadi JOIN oleh perencana kueri) dan JOIN bekerja lebih baik.

NOT IN formulasi keduanya membingungkan dengan adanya NULL commandid s dan bisa menjadi tidak efisien:

SELECT s.i AS missing_cmd
FROM generate_series(0,1000) s(i)
WHERE s.i NOT IN (SELECT commandid FROM results);

jadi saya akan menghindarinya. Dengan 1.000.000 baris, dua lainnya selesai dalam 1,2 detik dan NOT IN formulasi menjalankan CPU-bound sampai saya bosan dan membatalkannya.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menginstal driver PDO untuk PostgreSQL di Mac (menggunakan Zend untuk Eclipse)

  2. Permintaan SQL PostgreSQL untuk melintasi seluruh grafik yang tidak diarahkan dan mengembalikan semua tepi yang ditemukan

  3. Array multidimensi PostgreSQL

  4. PostgreSQL Upsert dengan klausa WHERE

  5. Alat untuk mengubah prosedur tersimpan t-sql (SQL Server) ke pgsql (postgre sql)