PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

PostgreSQL:Как да разбера липсващите числа в колона с помощта на generate_series()?

Дадени примерни данни:

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

Това работи:

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

както и тази алтернативна формулировка:

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;

И двете от горните изглежда водят до идентични планове за заявки в моите тестове, но трябва да сравните с вашите данни във вашата база данни с помощта на EXPLAIN ANALYZE за да видите кое е най-добро.

Обяснение

Имайте предвид, че вместо NOT IN Използвал съм NOT EXISTS с подзаявка в една формулировка и обикновен OUTER JOIN в другата. За DB сървъра е много по-лесно да ги оптимизира и избягва объркващи проблеми, които могат да възникнат с NULL s в NOT IN .

Първоначално предпочитах OUTER JOIN формулировка, но поне в 9.1 с моите тестови данни NOT EXISTS формулярът се оптимизира към същия план.

И двете ще се представят по-добре от NOT IN формулировка по-долу, когато серията е голяма, както е във вашия случай. NOT IN използвани за изискване на Pg да извърши линейно търсене на IN списък за всеки тестван кортеж, но изследването на плана на заявката предполага, че Pg може да е достатъчно умен, за да го хешира сега. NOT EXISTS (трансформирано в JOIN от инструмента за планиране на заявки) и JOIN работят по-добре.

NOT IN формулировката е объркваща и при наличието на NULL commandid s и може да бъде неефективно:

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

така че бих го избегнал. С 1 000 000 реда другите два завършиха за 1,2 секунди и NOT IN формулировката работеше в зависимост от процесора, докато не ми омръзна и я отмених.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Създайте уникален индекс на неуникална колона

  2. Грешка при картографиране на postgres масиви в Spring JPA

  3. Знак за нов ред на PostgreSQL

  4. pgAdmin3 проблеми с връзката

  5. Как да получите SQL текст от задействане на събитие на Postgres