sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL:Jak zjistit chybějící čísla ve sloupci pomocí create_series()?

Daná ukázková data:

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

Toto funguje:

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

stejně jako tato alternativní formulace:

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;

Zdá se, že oba výše uvedené vedou v mých testech k identickým plánům dotazů, ale měli byste je porovnat s daty ve vaší databázi pomocí EXPLAIN ANALYZE abyste viděli, která je nejlepší.

Vysvětlení

Všimněte si, že místo NOT IN Použil jsem NOT EXISTS s poddotazem v jedné formulaci a obyčejným OUTER JOIN v tom druhém. Pro DB server je mnohem snazší je optimalizovat a vyhne se matoucím problémům, které mohou nastat s NULL s v NOT IN .

Původně jsem preferoval OUTER JOIN formulace, ale alespoň v 9.1 s mými testovacími daty NOT EXISTS formulář se optimalizuje podle stejného plánu.

Oba budou fungovat lépe než NOT IN formulace níže, když je řada velká, jako ve vašem případě. NOT IN používá se k požadavku, aby Pg provedl lineární vyhledávání IN seznam pro každou testovanou n-tici, ale prozkoumání plánu dotazů naznačuje, že Pg může být dost chytrý na to, aby jej zahašoval hned. NOT EXISTS (přeměněno na JOIN plánovačem dotazů) a JOIN pracovat lépe.

NOT IN formulace je matoucí v přítomnosti NULL commandid s a může být neefektivní:

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

tak bych se tomu vyhnul. S 1 000 000 řádky jsou další dva dokončeny za 1,2 sekundy a NOT IN formulace běžela na CPU, dokud jsem se nezačal nudit a nezrušil jsem to.



  1. Příčky a High Water Mark v Oracle

  2. ztráta měřítka při provádění výpočtu

  3. Dynamicky získávejte názvy parametrů a aktuální hodnoty uvnitř uložené procedury T-SQL

  4. Dynamické pivotování hodnot sloupce MSSQL do záhlaví sloupce