Kwiinyanga ezininzi ezidlulileyo
Uyisebenzisile ngaphezulu kwamaxesha angama-6000 ukusukela ngoko, kodwa enye yezinto eziluncedo inokuba ayikhange iqatshelwe. imikhondo yolwakhiwo, ekhangeleka ngolu hlobo:
Mamela kubo kwaye izicelo zakho "ziya kuba silky silky". π
Kodwa ngokunzulu, iimeko ezininzi ezenza isicelo sicothe kwaye "sidla-kudla" ngokwezibonelelo, ziqhelekile kwaye zinokuqatshelwa ngolwakhiwo kunye neenkcukacha zesicwangciso.
Kule meko, umphuhlisi ngamnye akayi kukhangela ukhetho lokuphucula yedwa, exhomekeke kuphela kumava akhe - sinokumxelela ukuba kwenzeka ntoni apha, ingaba yintoni isizathu, kwaye indlela yokuza nesisombululo. Nto leyo esayenzayo.
Makhe sihlolisise ezi meko - ukuba zichazwa njani kwaye zeziphi iingcebiso ezikhokelela kuzo.
Ukucwiliswa okungcono kwisihloko, unokuqala ukuphulaphula ibhloko ehambelana nayo
#1: isalathisi "undersorting"
Nini
Bonisa i-invoyisi yokugqibela yomxhasi "LLC Kolokolchik".
Indlela yokuchonga
-> Limit
-> Sort
-> Index [Only] Scan [Backward] | Bitmap Heap Scan
Iingcebiso
Isalathisi esisetyenzisiweyo yandisa ngamasimi ohlobo.
Umzekelo:
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ΡΠ°ΠΊΡΠΎΠ²"
, (random() * 1000)::integer fk_cli; -- 1K ΡΠ°Π·Π½ΡΡ
Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΊΠ»ΡΡΠ΅ΠΉ
CREATE INDEX ON tbl(fk_cli); -- ΠΈΠ½Π΄Π΅ΠΊΡ Π΄Π»Ρ foreign key
SELECT
*
FROM
tbl
WHERE
fk_cli = 1 -- ΠΎΡΠ±ΠΎΡ ΠΏΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΉ ΡΠ²ΡΠ·ΠΈ
ORDER BY
pk DESC -- Ρ
ΠΎΡΠΈΠΌ Π²ΡΠ΅Π³ΠΎ ΠΎΠ΄Π½Ρ "ΠΏΠΎΡΠ»Π΅Π΄Π½ΡΡ" Π·Π°ΠΏΠΈΡΡ
LIMIT 1;
Unokuqaphela ngokukhawuleza ukuba iirekhodi ezingaphezu kwe-100 zathatyathwa yi-index, eziye zahlelwa zonke, kwaye kwasala enye kuphela.
Siyalungisa:
DROP INDEX tbl_fk_cli_idx;
CREATE INDEX ON tbl(fk_cli, pk DESC); -- Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ ΠΊΠ»ΡΡ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ
Nakwisampulu yamandulo - 8.5x ngokukhawuleza kwaye 33x ukufundwa okumbalwa. Isiphumo siya kucaca ngakumbi, ngakumbi "iinyani" onazo ngexabiso ngalinye. fk
.
Ndiqaphela ukuba isalathiso esinjalo siyakusebenza njenge "prefix" index akukho mbi kuneyangaphambili yeminye imibuzo fk
, apho ihlelwa khona pk
yayingekho kwaye ayikho (unokufunda ngakumbi malunga noku
#2: isalathisi sendlela (i-BitmapAnd)
Nini
Bonisa zonke izivumelwano zomthengi "LLC Kolokolchik" ezigqityiweyo egameni le "NJSC Lyutik".
Indlela yokuchonga
-> BitmapAnd
-> Bitmap Index Scan
-> Bitmap Index Scan
Iingcebiso
Yenza isalathiso esiyintlanganisela ngamasimi avela kwimithombo yomibini okanye ukwandisa enye yemihlaba ekhoyo ukusuka kweyesibini.
Umzekelo:
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ΡΠ°ΠΊΡΠΎΠ²"
, (random() * 100)::integer fk_org -- 100 ΡΠ°Π·Π½ΡΡ
Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΊΠ»ΡΡΠ΅ΠΉ
, (random() * 1000)::integer fk_cli; -- 1K ΡΠ°Π·Π½ΡΡ
Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΊΠ»ΡΡΠ΅ΠΉ
CREATE INDEX ON tbl(fk_org); -- ΠΈΠ½Π΄Π΅ΠΊΡ Π΄Π»Ρ foreign key
CREATE INDEX ON tbl(fk_cli); -- ΠΈΠ½Π΄Π΅ΠΊΡ Π΄Π»Ρ foreign key
SELECT
*
FROM
tbl
WHERE
(fk_org, fk_cli) = (1, 999); -- ΠΎΡΠ±ΠΎΡ ΠΏΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΉ ΠΏΠ°ΡΠ΅
Siyalungisa:
DROP INDEX tbl_fk_org_idx;
CREATE INDEX ON tbl(fk_org, fk_cli);
Apha inzuzo incinci, kuba iBitmap Heap Scan isebenza ngokwayo. Kodwa kunjalo 7x ngokukhawuleza kwaye 2.5x ukufundwa okumbalwa.
#3: Ukudibanisa izalathisi (BitmapOr)
Nini
Bonisa izicelo zokuqala ezingama-20 "ezakhe" okanye ezingabiwanga ukuze ziqwalaselwe, ezizezakhe eziphambili.
Indlela yokuchonga
-> BitmapOr
-> Bitmap Index Scan
-> Bitmap Index Scan
Iingcebiso
Sebenzisa IMANYANO [ZONKE] ukudibanisa subqueries kwimeko nganye OKANYE iibhloko.
Umzekelo:
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ΡΠ°ΠΊΡΠΎΠ²"
, CASE
WHEN random() < 1::real/16 THEN NULL -- Ρ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡΡ 1:16 Π·Π°ΠΏΠΈΡΡ "Π½ΠΈΡΡΡ"
ELSE (random() * 100)::integer -- 100 ΡΠ°Π·Π½ΡΡ
Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΊΠ»ΡΡΠ΅ΠΉ
END fk_own;
CREATE INDEX ON tbl(fk_own, pk); -- ΠΈΠ½Π΄Π΅ΠΊΡ Ρ "Π²ΡΠΎΠ΄Π΅ ΠΊΠ°ΠΊ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡΠ΅ΠΉ" ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΎΠΉ
SELECT
*
FROM
tbl
WHERE
fk_own = 1 OR -- ΡΠ²ΠΎΠΈ
fk_own IS NULL -- ... ΠΈΠ»ΠΈ "Π½ΠΈΡΡΠΈ"
ORDER BY
pk
, (fk_own = 1) DESC -- ΡΠ½Π°ΡΠ°Π»Π° "ΡΠ²ΠΎΠΈ"
LIMIT 20;
Siyalungisa:
(
SELECT
*
FROM
tbl
WHERE
fk_own = 1 -- ΡΠ½Π°ΡΠ°Π»Π° "ΡΠ²ΠΎΠΈ" 20
ORDER BY
pk
LIMIT 20
)
UNION ALL
(
SELECT
*
FROM
tbl
WHERE
fk_own IS NULL -- ΠΏΠΎΡΠΎΠΌ "Π½ΠΈΡΡΠΈ" 20
ORDER BY
pk
LIMIT 20
)
LIMIT 20; -- Π½ΠΎ Π²ΡΠ΅Π³ΠΎ - 20, Π±ΠΎΠ»ΡΡΠ΅ ΠΈ Π½Π΅ Π½Π°Π΄ΠΎ
Sithathe ithuba lokuba zonke iirekhodi ezingama-20 eziyimfuneko zafunyanwa kwangoko kwibhloko yokuqala, ke eyesibini, neyona βibizi kakhuluβ i-Bitmap Heap Scan, ayizange iphunyezwe - ngenxa yoko. 22x ngokukhawuleza, 44x ukufunda okumbalwa!
Ibali elineenkcukacha malunga nale ndlela yokuphucula kwimizekelo ebonakalayo inokufundwa kumanqaku
I-PostgreSQL Antipatterns: I-JOIN enobungozi kunye ne-ORs ΠΈI-PostgreSQL Antipatterns: Ibali lokuCwangciswa okuPhindayo kokuKhangela ngeGama, okanye "Ukuphucula emva naphambili" .Uguqulelo oluqhelekileyo ukhetho olucwangcisiweyo ngamaqhosha amaninzi (kwaye hayi nje ipere ye const / NULL) kuxoxwa ngayo kwinqaku
SQL HowTo: bhala ixesha-loop ngokuthe ngqo kumbuzo, okanye "Elementary three-way" .
#4: Sifunda kakhulu
Nini
Njengomthetho, kwenzeka xa ufuna "ukuncamathisela esinye isihluzi" kwisicelo esele sikhona.
βKwaye awunayo into efanayo, kodwa ngamaqhosha eperile? Β» ifilimu "Isandla seDiamond"
Umzekelo, ukulungisa umsebenzi ongasentla, bonisa izicelo zokuqala ezingama-20 "ezibalulekileyo" zokuqhubekeka, nokuba ziyintoni na injongo yazo.
Indlela yokuchonga
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& 5 Γ rows < RRbF -- ΠΎΡΡΠΈΠ»ΡΡΡΠΎΠ²Π°Π½ΠΎ >80% ΠΏΡΠΎΡΠΈΡΠ°Π½Π½ΠΎΠ³ΠΎ
&& loops Γ RRbF > 100 -- ΠΈ ΠΏΡΠΈ ΡΡΠΎΠΌ Π±ΠΎΠ»ΡΡΠ΅ 100 Π·Π°ΠΏΠΈΡΠ΅ΠΉ ΡΡΠΌΠΌΠ°ΡΠ½ΠΎ
Iingcebiso
Yenza [okungakumbi] okukhethekileyo isalathiso esinegatya apho okanye uquke imimandla eyongezelelweyo kwisalathiso.
Ukuba imeko yokucoca "i-static" kwimisebenzi yakho - oko kukuthi alubandakanyi ukwandiswa uluhlu lwamaxabiso kwixesha elizayo - kungcono ukusebenzisa isalathisi apho. Iimo ezahlukeneyo ze-boolean/enum zingena kakuhle kolu didi.
Ukuba imeko yokucoca inokuthatha amaxabiso ahlukeneyo, kungcono ukwandisa isalathisi kunye nale mihlaba - njengakwimeko nge-BitmapAnd ngasentla.
Umzekelo:
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ΡΠ°ΠΊΡΠΎΠ²"
, CASE
WHEN random() < 1::real/16 THEN NULL
ELSE (random() * 100)::integer -- 100 ΡΠ°Π·Π½ΡΡ
Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΊΠ»ΡΡΠ΅ΠΉ
END fk_own
, (random() < 1::real/50) critical; -- 1:50, ΡΡΠΎ Π·Π°ΡΠ²ΠΊΠ° "ΠΊΡΠΈΡΠΈΡΠ½Π°Ρ"
CREATE INDEX ON tbl(pk);
CREATE INDEX ON tbl(fk_own, pk);
SELECT
*
FROM
tbl
WHERE
critical
ORDER BY
pk
LIMIT 20;
Siyalungisa:
CREATE INDEX ON tbl(pk)
WHERE critical; -- Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ "ΡΡΠ°ΡΠΈΡΠ½ΠΎΠ΅" ΡΡΠ»ΠΎΠ²ΠΈΠ΅ ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΠΈ
Njengoko ubona, ukuhluzwa kwisicwangciso kuphelile ngokupheleleyo, kwaye isicelo siye saba Amaxesha ama-5 ngokukhawuleza.
#5: itafile enqabileyo
Nini
Iinzame ezahlukeneyo zokwenza umgca wokucwangcisa umsebenzi wakho, xa inani elikhulu lohlaziyo / ukususwa kweerekhodi kwitafile kukhokelela kwimeko yenani elikhulu leerekhodi "ezifileyo".
Indlela yokuchonga
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& loops Γ (rows + RRbF) < (shared hit + shared read) Γ 8
-- ΠΏΡΠΎΡΠΈΡΠ°Π½ΠΎ Π±ΠΎΠ»ΡΡΠ΅ 1KB Π½Π° ΠΊΠ°ΠΆΠ΄ΡΡ Π·Π°ΠΏΠΈΡΡ
&& shared hit + shared read > 64
Iingcebiso
Yenza ngesandla rhoqo IVACUUM [EGCWELE] okanye ukuphumeza ngokwaneleyo ukusetyenzwa rhoqo
Kwiimeko ezininzi, iingxaki ezinjalo zibangelwa kukubekwa kwemibuzo engalunganga xa kubizwa ingqiqo yeshishini, njengaleyo kuxoxwe ngayo kuyo
I-PostgreSQL Antipatterns: imikhosi yokulwa "yabafileyo" .Kodwa kufuneka siqonde ukuba ne-VACUUM FULL ayinakuhlala inceda. Kwiimeko ezinjalo, kufuneka uziqhelanise ne-algorithm evela kwinqaku.
I-DBA: xa i-VACUUM idlula, sicoca itafile ngesandla .
#6: ukufunda ukusuka "kumbindi" wesalathiso
Nini
Kubonakala ngathi bafunde kancinci, kwaye yonke into yayifakwe kwisalathiso, kwaye abazange bahluze nabani na ngokungaphezulu-kodwa kunjalo, amaphepha amaninzi afundwe kunokuba singathanda.
Indlela yokuchonga
-> Index [Only] Scan [Backward]
&& loops Γ (rows + RRbF) < (shared hit + shared read) Γ 8
-- ΠΏΡΠΎΡΠΈΡΠ°Π½ΠΎ Π±ΠΎΠ»ΡΡΠ΅ 1KB Π½Π° ΠΊΠ°ΠΆΠ΄ΡΡ Π·Π°ΠΏΠΈΡΡ
&& shared hit + shared read > 64
Iingcebiso
Thatha ujongo olusondeleyo kulwakhiwo lwesalathiso esisetyenzisiweyo kunye nemimandla ephambili ekhankanyiweyo kumbuzo - kakhulu kunokwenzeka, inxalenye yesalathiso ayimiselwanga. Kuya kufuneka wenze isalathiso esifanayo, kodwa ngaphandle kwemihlaba yesimaphambili, okanye
Umzekelo:
CREATE TABLE tbl AS
SELECT
generate_series(1, 100000) pk -- 100K "ΡΠ°ΠΊΡΠΎΠ²"
, (random() * 100)::integer fk_org -- 100 ΡΠ°Π·Π½ΡΡ
Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΊΠ»ΡΡΠ΅ΠΉ
, (random() * 1000)::integer fk_cli; -- 1K ΡΠ°Π·Π½ΡΡ
Π²Π½Π΅ΡΠ½ΠΈΡ
ΠΊΠ»ΡΡΠ΅ΠΉ
CREATE INDEX ON tbl(fk_org, fk_cli); -- Π²ΡΠ΅ ΠΏΠΎΡΡΠΈ ΠΊΠ°ΠΊ Π² #2
-- ΡΠΎΠ»ΡΠΊΠΎ Π²ΠΎΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΈΠ½Π΄Π΅ΠΊΡ ΠΏΠΎ fk_cli ΠΌΡ ΡΠΆΠ΅ ΠΏΠΎΡΡΠΈΡΠ°Π»ΠΈ Π»ΠΈΡΠ½ΠΈΠΌ ΠΈ ΡΠ΄Π°Π»ΠΈΠ»ΠΈ
SELECT
*
FROM
tbl
WHERE
fk_cli = 999 -- Π° fk_org Π½Π΅ Π·Π°Π΄Π°Π½ΠΎ, Ρ
ΠΎΡΡ ΡΡΠΎΠΈΡ Π² ΠΈΠ½Π΄Π΅ΠΊΡΠ΅ ΡΠ°Π½ΡΡΠ΅
LIMIT 20;
Yonke into ibonakala ilungile, nangokwemigaqo yesalathiso, kodwa ngandlela-thile iyakrokra - kwirekhodi nganye ye-20 efundwayo, amaphepha e-4 edatha kwafuneka athatyathwe, i-32KB ngerekhodi - ayinesibindi? Ewe kunye negama lesalathisi tbl_fk_org_fk_cli_idx
ikhokelela kwingcinga.
Siyalungisa:
CREATE INDEX ON tbl(fk_cli);
Ngequbuliso - Amaxesha angama-10 ngokukhawuleza kunye namaxesha ama-4 ngaphantsi ukufunda!
Ngeminye imizekelo yokusetyenziswa ngokungafanelekanga kwezalathisi, bona inqaku
I-DBA: fumana izalathisi ezingenamsebenzi .
#7: CTE Γ CTE
Nini
Ngesicelo amanqaku "amafutha" CTE ukusuka kwiitafile ezahlukeneyo, kwaye emva koko wagqiba ukwenza phakathi kwabo JOIN
.
Ityala lifanelekile kwiinguqulelo ezingezantsi kwe-v12 okanye izicelo nge WITH MATERIALIZED
.
Indlela yokuchonga
-> CTE Scan
&& loops > 10
&& loops Γ (rows + RRbF) > 10000
-- ΡΠ»ΠΈΡΠΊΠΎΠΌ Π±ΠΎΠ»ΡΡΠΎΠ΅ Π΄Π΅ΠΊΠ°ΡΡΠΎΠ²ΠΎ ΠΏΡΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅ CTE
Iingcebiso
Sihlalutye isicelo ngononophelo
#8: tshintshela kwidisk (ixesha libhaliwe)
Nini
Ukusetyenzwa kwexesha elinye (ukuhlelwa okanye ukwahlulahlula) inani elikhulu leerekhodi alingeni kwimemori eyabelwe oku.
Indlela yokuchonga
-> *
&& temp written > 0
Iingcebiso
Ukuba inani lememori elisetyenziswe ngumsebenzi aligqithisi kakhulu ixabiso elimiselweyo leparameter SET [LOCAL]
ngesicelo esithile/intengiselwano.
Umzekelo:
SHOW work_mem;
-- "16MB"
SELECT
random()
FROM
generate_series(1, 1000000)
ORDER BY
1;
Siyalungisa:
SET work_mem = '128MB'; -- ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ Π·Π°ΠΏΡΠΎΡΠ°
Ngenxa yezizathu ezicacileyo, ukuba imemori kuphela isetyenzisiweyo kwaye kungekhona idiski, ngoko umbuzo uya kukhawuleza kakhulu. Ngexesha elifanayo, inxalenye yomthwalo iphinda isuswe kwi-HDD.
Kodwa kufuneka uqonde ukuba ukwaba imemori eninzi akusayi kuhlala kusebenze - akuyi kwanela wonke umntu.
#9: Amanani angasebenziyo
Nini
Ininzi yagalelwa kwisiseko kwangoko, kodwa babengenaxesha lokuyigxotha ANALYZE
.
Indlela yokuchonga
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& ratio >> 10
Iingcebiso
Chitha okufanayo ANALYZE
.
Le meko ichazwe ngokubanzi kwi
I-PostgreSQL Antipatterns: izibalo ziyintloko yento yonke .
#10: "ikhona into engalunganga"
Nini
Kwakukho isitshixo esilinde isicelo esikhuphisanayo, okanye kwakungekho zixhobo zaneleyo ze-CPU/hypervisor hardware.
Indlela yokuchonga
-> *
&& (shared hit / 8K) + (shared read / 1K) < time / 1000
-- RAM hit = 64MB/s, HDD read = 8MB/s
&& time > 100ms -- ΡΠΈΡΠ°Π»ΠΈ ΠΌΠ°Π»ΠΎ, Π½ΠΎ ΡΠ»ΠΈΡΠΊΠΎΠΌ Π΄ΠΎΠ»Π³ΠΎ
Iingcebiso
Sebenzisa yangaphandle inkqubo yokubeka iliso umncedisi wokuthintela okanye ukusetyenziswa kobutyebi ngokungaqhelekanga. Sele sithethile malunga nenguqulelo yethu yokulungiselela le nkqubo kumakhulu amaseva.
umthombo: www.habr.com