Neke atu i te 6000 nga wa kua whakamahia e koe, engari ko tetahi o nga waahanga kare pea i kitea ko tohu hanganga, he penei te ahua:
Whakarongo ki a raatau, ka "maeneene me te hiraka" o tono. 🙂
Engari he mea nui, he maha nga ahuatanga ka puhoi te tono me te hiakai rawa he angamaheni ka taea te mohio ma te hanganga me nga raraunga o te mahere.
I tenei keehi, kaore ia kaiwhakawhanake takitahi e rapu i tetahi whiringa arotautanga ki a ia ano, ma te whakawhirinaki anake ki tana wheako - ka taea e taatau te korero ki a ia he aha te mea kei konei, he aha te take, me me pehea te whakatata ki te otinga. Koia ta matou mahi.
Kia ata titiro ki enei keehi - he pehea te whakamaaramatanga me te aha nga taunakitanga ka arahi.
Kia pai ake te ruku i a koe ki roto i te kaupapa, ka taea e koe te whakarongo tuatahi ki te poraka e rite ana mai taku purongo i PGConf.Russia 2020, katahi ka neke ki te tātaritanga mo ia tauira:
#1: taupū "whakaraupapa"
Ina whakatika
Whakaatuhia te nama hou mo te kaihoko "LLC Kolokolchik".
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;
Ahakoa i runga i taua tauira tuatahi - 8.5 nga wa tere ake me te 33 nga wa iti ake te panui. Ko te nui ake o nga "meka" kei a koe mo ia uara, ka tino kitea te paanga fk.
Ka kite ahau ka mahi taua taurangi hei tohu "prefix" kaore he kino atu i mua mo etahi atu patai fk, kei hea te whakariterite pk karekau karekau (ka taea e koe te panui atu mo tenei i roto i taku tuhinga mo te rapu i nga taurangi kore whai hua). Tae atu, ka whakarato noa tautoko matua tawahi i runga i tenei mara.
#2: te haupae taupū (BitmapMe)
Ina whakatika
Whakaatuhia nga whakaaetanga katoa mo te kaihoko "LLC Kolokolchik", ka mutu mo "NAO Buttercup".
Me pehea te tautuhi
-> BitmapAnd
-> Bitmap Index Scan
-> Bitmap Index Scan
tūtohutanga
waihanga taupū hiato mā ngā āpure mai i ngā mea taketake e rua, ka whakawhānuihia rānei tētahi o ngā āpure me ngā āpure mai i te tuarua.
Hei tauira:
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); -- отбор по конкретной паре
He iti ake te utu i konei, na te mea ko te Bitmap Heap Scan he tino whai hua ki a ia ano. Engari ahakoa 7 nga wa tere ake me te 2.5 nga wa iti ake te panui.
#3: Hanumi taupū (BitmapOr)
Ina whakatika
Whakaatuhia nga 20 tawhito tuatahi "tatou" me nga tono kaore ano i tohua mo te tukatuka, me o raatau te kaupapa matua.
Me pehea te tautuhi
-> BitmapOr
-> Bitmap Index Scan
-> Bitmap Index Scan
tūtohutanga
Whakamahia UNION [KATOA] ki te whakakotahi i nga paatai mo ia poraka-OR o nga tikanga.
Hei tauira:
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;
(
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, больше и не надо
I whai hua matou i te mea ko nga rekoata e 20 e hiahiatia ana i tae tonu mai ki te poraka tuatahi, na ko te tuarua, me te "nui ake" Bitmap Heap Scan, kaore i mahia - i te mutunga. 22x tere ake, 44x iti ake te panui!
Ka rite ki te tikanga, ka puta ina hiahia koe ki te "whakapiri i tetahi atu tātari" ki tetahi tono o mua.
"A kaore koe i te mea kotahi, engari me nga patene whaea-o-peara? " kiriata "The Diamond Arm"
Hei tauira, ko te whakarereke i te mahi i runga ake nei, whakaatu i nga tono tuatahi 20 "arohaehae" mo te tukatuka, ahakoa he aha te kaupapa.
Me pehea te tautuhi
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& 5 × rows < RRbF -- отфильтровано >80% прочитанного
&& loops × RRbF > 100 -- и при этом больше 100 записей суммарно
tūtohutanga
Waihanga [atu] motuhake taupū me te ahua WHERE whakauruhia ranei etahi atu mara ki te taurangi.
Mena he "pateko" te ahuatanga tātari mo o kaupapa - ara e kore e kii te roha rarangi o nga uara kei te heke mai - he pai ake te whakamahi i te tohu WHERE. He pai nga ahuatanga boolean/enum ki tenei waahanga.
Ki te te huru tātari ka taea te tango i nga tikanga rereke, katahi ka pai ake te whakawhanui i te taurangi me enei mara - penei i te ahuatanga me BitmapAnd i runga ake nei.
Hei tauira:
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;
Ka kite koe, kua ngaro katoa te tātari i te mahere, kua riro te tono 5 nga wa tere ake.
#5: tepu iti
Ina whakatika
He maha nga ngana ki te hanga i a koe ake rarangi tukatuka mahi, i te mea he maha nga whakahou / mukunga o nga rekoata i runga i te teepu ka arahi ki te ahua o te maha o nga rekoata "mate".
Me pehea te tautuhi
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& loops × (rows + RRbF) < (shared hit + shared read) × 8
-- прочитано больше 1KB на каждую запись
&& shared hit + shared read > 64
tūtohutanga
Me mahi ā-ringa i ia te wā KAUPAPA [KATI] te whakatutuki whakangungu auau ranei mokohau aunoa ma te whakatikatika i ona tawhā, tae atu ki mo tetahi tepu motuhake.
Te ahua nei he iti ta matou panui, a kua taurangihia nga mea katoa, a kaore matou i tarai i nga tangata i te taikaha - engari he nui noa atu nga wharangi ka panuihia e matou.
Me pehea te tautuhi
-> Index [Only] Scan [Backward]
&& loops × (rows + RRbF) < (shared hit + shared read) × 8
-- прочитано больше 1KB на каждую запись
&& shared hit + shared read > 64
tūtohutanga
Tirohia te hanganga o te taupū i whakamahia me nga mara matua kua tohua i roto i te patai - te nuinga pea karekau he waahanga o te taurangi i tohua. Ko te nuinga ka whai koe ki te hanga i tetahi taurangi rite, engari karekau he mara prefix ranei ako ki te huri i o raatau uara.
Hei tauira:
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;
He pai nga mea katoa, ahakoa i runga i te taurangi, engari he mea whakapae - mo ia rekoata 20 ka panuihia, me tango e matou nga wharangi raraunga e 4, 32KB mo ia rekoata - kaore he maia? Me te ingoa tohu tbl_fk_org_fk_cli_idx whakahihiri whakaaro.
Ko te tukatuka kotahi-wa (te wehewehe, te wehewehe ranei) o te maha o nga rekoata kaore e uru ki te mahara kua tohaina mo tenei.
Me pehea te tautuhi
-> *
&& temp written > 0
tūtohutanga
Mena ko te nui o te mahara e whakamahia ana e te mahi kaore e nui ake i te uara kua tohua o te tawhā mahi_mem, he mea tika kia whakatika. Ka taea e koe i roto i te whirihora mo te katoa, ka taea ranei e koe SET [LOCAL] mo te tono/tauwhitinga motuhake.
Hei tauira:
SHOW work_mem;
-- "16MB"
SELECT
random()
FROM
generate_series(1, 1000000)
ORDER BY
1;
Mo nga tino take, mena ka whakamahia te mahara anake, kaua ko te kopae, ka tere ake te mahi o te patai. I te wa ano, ka tangohia ano tetahi waahanga o te kawenga mai i te HDD.
Engari me mohio koe kaore e taea e koe te toha i nga wa katoa me te maha o nga mahara - kaore e ranea mo te katoa.
#9: nga tatauranga kore whai take
Ina whakatika
I ringihia e ratou he maha ki roto i te papaarangi i te wa kotahi, engari kaore he wa ki te peia atu ANALYZE.
Me pehea te tautuhi
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& ratio >> 10
I tatari mo te raka i tukuna e tetahi tono whakataetae, he iti rawa ranei nga rauemi taputapu CPU/hypervisor.
Me pehea te tautuhi
-> *
&& (shared hit / 8K) + (shared read / 1K) < time / 1000
-- RAM hit = 64MB/s, HDD read = 8MB/s
&& time > 100ms -- читали мало, но слишком долго
tūtohutanga
Whakamahia he waho pūnaha aroturuki tūmau mo te aukati, te kohi rawa rereke ranei. Kua korero kee matou mo ta matou putanga mo te whakarite i tenei mahi mo nga rau o nga kaitoro konei и konei.