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;
-> BitmapAnd
-> Bitmap Index Scan
-> Bitmap Index Scan
سپارښتنې
رامنځ ته مرکب شاخص د دواړو منابعو ساحو په واسطه یا له دوهم څخه موجوده ساحو څخه یوه پراخه کړئ.
بېلګه:
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); -- отбор по конкретной паре
دلته لاسته راوړنه لږه ده، ځکه چې د بټ میپ هیپ سکین پخپله خورا اغیزمن دی. خو په هر صورت 7x ګړندی او 2.5x لږ لوستل.
#3: د شاخصونو ترکیب (BitmapOr)
کله کوي
د پروسس کولو لپاره لومړی 20 زاړه "خپل" یا غیر سپارل شوي غوښتنې وښایاست، د خپل لومړیتوب سره.
د پیژندلو څرنګوالی
-> BitmapOr
-> Bitmap Index Scan
-> Bitmap Index Scan
سپارښتنې
استعمال اتحادیه [ټول] د هر حالت یا بلاک لپاره فرعي پوښتنو سره یوځای کول.
بېلګه:
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, больше и не надо
د یوې قاعدې په توګه، دا واقع کیږي کله چې تاسو غواړئ د موجوده غوښتنې سره "بل فلټر ضمیمه کړئ".
"او تاسو ورته نه لرئ، مګر د موتی تڼیو سره؟ » فلم "د الماس لاس"
د مثال په توګه، د پورتنۍ دندې تعدیل، د پروسس لپاره لومړنۍ 20 زاړه "مهم" غوښتنې ښکاره کړئ، پرته له دې چې هدف یې په پام کې ونیول شي.
د پیژندلو څرنګوالی
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& 5 × rows < RRbF -- отфильтровано >80% прочитанного
&& loops × RRbF > 100 -- и при этом больше 100 записей суммарно
سپارښتنې
[نور] تخصص جوړ کړئ د WHERE بند سره شاخص یا په شاخص کې اضافي ساحې شامل کړئ.
که د فلټر کولو حالت ستاسو د دندو لپاره "جامد" وي - دا دی پراخول شامل نه دي په راتلونکي کې د ارزښتونو لیست - دا غوره ده چې د WHERE شاخص وکاروئ. مختلف بولین / اینوم حالتونه پدې کټګورۍ کې ښه فټ کوي.
که د چاڼ حالت کولی شي مختلف ارزښتونه واخلي، دا غوره ده چې د دې ساحو سره شاخص پراخه کړئ - لکه څنګه چې د بټ میپ او پورته حالت کې.
بېلګه:
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;
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;
هرڅه سم ښکاري، حتی د شاخص په شرایطو کې، مګر یو څه شکمن دي - د هر 20 ریکارډونو لوستلو لپاره، د 4 پاڼو ډاټا باید کم شي، په هر ریکارډ کې 32KB - ایا دا زړور نه دی؟ هو او د شاخص نوم tbl_fk_org_fk_cli_idx فکر ته لار پیدا کوي.