PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

PostgreSQL:Làm thế nào để tìm ra các số còn thiếu trong một cột bằng cách sử dụng create_series ()?

Dữ liệu mẫu được cung cấp:

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

Điều này hoạt động:

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

cũng như công thức thay thế này:

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;

Cả hai điều trên dường như dẫn đến các kế hoạch truy vấn giống hệt nhau trong các thử nghiệm của tôi, nhưng bạn nên so sánh với dữ liệu trên cơ sở dữ liệu của mình bằng cách sử dụng EXPLAIN ANALYZE để xem cái nào là tốt nhất.

Giải thích

Lưu ý rằng thay vì NOT IN Tôi đã sử dụng NOT EXISTS với một truy vấn con trong một công thức và một OUTER JOIN thông thường trong cái khác. Máy chủ DB tối ưu hóa những điều này dễ dàng hơn nhiều và nó tránh được các vấn đề khó hiểu có thể phát sinh với NULL s trong NOT IN .

Ban đầu tôi thích OUTER JOIN công thức, nhưng ít nhất trong 9.1 với dữ liệu thử nghiệm của tôi, NOT EXISTS biểu mẫu tối ưu hóa cho cùng một kế hoạch.

Cả hai sẽ hoạt động tốt hơn NOT IN công thức bên dưới khi chuỗi lớn, như trong trường hợp của bạn. NOT IN được sử dụng để yêu cầu Pg thực hiện tìm kiếm tuyến tính đối với IN danh sách cho mọi tuple đang được kiểm tra, nhưng việc kiểm tra kế hoạch truy vấn cho thấy Pg có thể đủ thông minh để băm nó ngay bây giờ. NOT EXISTS (được chuyển thành JOIN bởi công cụ lập kế hoạch truy vấn) và JOIN hoạt động tốt hơn.

NOT IN công thức vừa gây nhầm lẫn khi có NULL commandid s và có thể không hiệu quả:

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

vì vậy tôi muốn tránh nó. Với 1.000.000 hàng, hai hàng còn lại hoàn thành trong 1,2 giây và NOT IN công thức chạy bị ràng buộc bởi CPU cho đến khi tôi cảm thấy nhàm chán và hủy bỏ nó.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Có gì mới trong PostgreSQL 11

  2. Dense_rank chuyển đổi Oracle sang Postgresql đầu tiên

  3. Làm thế nào để một người viết một CASCADE XÓA cho bưu điện?

  4. không thể khởi động lại postgres trên mac os x

  5. Có thể bắt lỗi vi phạm khóa ngoại trong postgres không