Mga Antipattern sa PostgreSQL: "Kinahanglan usa ra ang nahabilin!"
Sa SQL, imong gihulagway ang "unsa" gusto nimong makab-ot, dili "unsaon" kini kinahanglan ipatuman. Busa, ang problema sa pagpalambo sa mga pangutana sa SQL sa estilo sa "ingon nga kini nadungog mao ang paagi nga kini gisulat" nagpuli sa iyang dapit sa kadungganan, uban sa mga bahin sa pagkalkula sa mga kondisyon sa SQL.
Karon, gamit ang labi ka yano nga mga pananglitan, tan-awon naton kung unsa ang mahimo niini sa konteksto sa paggamit GROUP/DISTINCT ΠΈ LIMIT uban kanila.
Karon, kung nagsulat ka sa hangyo "Ikonektar una kini nga mga timailhan, ug dayon ilabay ang tanan nga mga duplicate, kinahanglan nga usa na lang ang nahabilin kopya para sa matag yawe" - ingon niini kung giunsa kini molihok, bisan kung ang koneksyon dili kinahanglan.
Ug usahay ikaw swerte ug kini "nagtrabaho lang", usahay kini adunay dili maayo nga epekto sa pasundayag, ug usahay kini naghatag mga epekto nga wala damha gikan sa punto sa panglantaw sa developer.
Aw, tingali dili kaayo talagsaon, apan ...
βSweet coupleβ: AMBAY + DISTINCT
SELECT DISTINCT
X.*
FROM
X
JOIN
Y
ON Y.fk = X.pk
WHERE
Y.bool_condition;
Klaro kon unsay ilang gusto pilia ang mga rekord X diin adunay mga rekord sa Y nga may kalabutan sa natuman nga kondisyon. Nagsulat og hangyo pinaagi sa JOIN β nakabaton ug pipila ka pk values ββββsa makadaghang higayon (eksaktong pila ka angay nga mga entry ang nagpakita sa Y). Unsaon pagtangtang? Sigurado DISTINCT!
Labi na nga "makapalipay" kung alang sa matag X-record adunay daghang gatos nga may kalabutan nga Y-record, ug dayon ang mga duplicate mabayanihon nga gikuha ...
Unsaon pag-ayo? Sa pagsugod, hinumdomi nga ang problema mahimong mabag-o sa "pilia ang mga rekord X diin sa Y adunay labing menos USA nga nalangkit sa natuman nga kondisyon" - pagkahuman, wala kami magkinahanglan bisan unsa gikan sa Y-record mismo.
Nested EXISTS
SELECT
*
FROM
X
WHERE
EXISTS(
SELECT
NULL
FROM
Y
WHERE
fk = X.pk AND
bool_condition
LIMIT 1
);
Ang ubang mga bersyon sa PostgreSQL nakasabut nga sa EXISTS igo na nga makit-an ang una nga entry nga moabut, ang mga tigulang wala. Busa mas gusto nako nga kanunay ipahibalo LIMIT 1 sa sulod EXISTS.
LATERAL AMBAY
SELECT
X.*
FROM
X
, LATERAL (
SELECT
Y.*
FROM
Y
WHERE
fk = X.pk AND
bool_condition
LIMIT 1
) Y
WHERE
Y IS DISTINCT FROM NULL;
βNganong mobayad man og dugangβ: DISTINCT [ON] + LIMIT 1
Ang usa ka dugang nga kaayohan sa ingon nga mga pagbag-o sa pangutana mao ang katakus nga dali nga limitahan ang pagpangita alang sa mga rekord kung kinahanglan ra ang usa o pipila niini, sama sa mosunod nga kaso:
SELECT DISTINCT ON(X.pk)
*
FROM
X
JOIN
Y
ON Y.fk = X.pk
LIMIT 1;
Karon among gibasa ang hangyo ug gisulayan nga masabtan kung unsa ang gisugyot nga buhaton sa DBMS:
pagkonektar sa mga timailhan
talagsaon sa X.pk
gikan sa nahabilin nga mga entri, pagpili og usa
Busa unsa ang imong nakuha? "Usa ra ka entry" gikan sa mga talagsaon - ug kung atong kuhaon kining usa sa mga dili talagsaon, mausab ba ang resulta?
SELECT
*
FROM
(
SELECT
*
FROM
X
-- ΡΡΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΡΡΠ½ΡΡΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈΡ ΡΡΠ»ΠΎΠ²ΠΈΠΉ
LIMIT 1 -- +1 Limit
) X
JOIN
Y
ON Y.fk = X.pk
LIMIT 1;
Ug parehas nga hilisgutan sa GROUP BY + LIMIT 1.
βMangutana lang koβ: implicit GROUP + LIMIT
Ang susamang mga butang mahitabo sa lain-laing mga non-emptiness checks mga timailhan o CTE samtang nagpadayon ang hangyo:
...
CASE
WHEN (
SELECT
count(*)
FROM
X
LIMIT 1
) = 0 THEN ...
Aggregate functions (count/min/max/sum/...) malampuson nga gipatuman sa tibuok set, bisan walay klaro nga mga instruksyon GROUP BY. Lamang uban sa LIMIT dili kaayo sila mahigalaon.
Makahunahuna ang developer "kung adunay mga rekord didto, nan kinahanglan nako dili labaw pa sa LIMIT". Apan ayaw kana buhata! Tungod kay alang sa base kini mao ang:
isipa ang ilang gusto sumala sa tanang rekord
hatag ug daghang linya sa ilang gipangayo
Depende sa gipunting nga mga kondisyon, angay nga himuon ang usa sa mga mosunud nga kapuli:
(count + LIMIT 1) = 0saNOT EXISTS(LIMIT 1)
(count + LIMIT 1) > 0saEXISTS(LIMIT 1)
count >= Nsa(SELECT count(*) FROM (... LIMIT N))
"Pila ang ibitay sa gramo": DISTINCT + LIMIT
SELECT DISTINCT
pk
FROM
X
LIMIT $1
Ang usa ka walay pulos nga developer mahimong sinsero nga nagtuo nga ang hangyo mohunong sa pagpatuman. sa diha nga nakit-an namon ang $1 sa una nga lainlaing mga kantidad nga makita.
Usahay sa umaabot mahimo kini ug molihok salamat sa usa ka bag-ong node Index Laktawan Scan, ang pagpatuman niini sa pagkakaron ginabuhat, apan dili pa.
Sa pagkakaron una ang tanan nga mga rekord makuha, talagsaon, ug gikan lamang kanila ang kantidad nga gipangayo ibalik. Labi na nga makapasubo kung gusto namon ang usa ka butang nga sama $ 1 = 4, ug adunay gatusan ka libo nga mga rekord sa lamesa...