рдзреЗрд░реИ рдорд╣рд┐рдирд╛ рдЕрдШрд┐ - рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ PostgreSQL рдорд╛ред
рддрдкрд╛рдИрдВрд▓реЗ рдпрд╕рд▓рд╛рдИ рд╡рд░реНрд╖реМрдВрджреЗрдЦрд┐ рем,режрежреж рднрдиреНрджрд╛ рдмрдвреА рдкрдЯрдХ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рд╕рдХреНрдиреБрднрдПрдХреЛ рдЫ, рддрд░ рдпрд╕рдХреЛ рдПрдЙрдЯрд╛ рдЙрдкрдпреЛрдЧреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╕реИрд▓реЗ рдирджреЗрдЦреЗрдХреЛ рд╣реБрди рд╕рдХреНрдЫ - рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рд╕рдВрдХреЗрддрд╣рд░реВ, рдЬреБрди рдпрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдЫ:

рдЙрдиреАрд╣рд░реВрдХреЛ рдХреБрд░рд╛ рд╕реБрдиреНрдиреБрд╣реЛрд╕реН, рдЕрдирд┐ рддрдкрд╛рдИрдВрдХрд╛ рдЕрдиреБрд░реЛрдзрд╣рд░реВ "рдЪрд┐рд▓реНрд▓реЛ рд░ рд░реЗрд╢рдореА" рд╣реБрдиреЗрдЫрдиреНред ЁЯЩВ
рддрд░ рдЧрдореНрднреАрд░рддрд╛рдкреВрд░реНрд╡рдХ, рдзреЗрд░реИ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рд╣рд░реВ рдЫрдиреН рдЬрд╕рд▓реЗ рдХреНрд╡реЗрд░реАрд▓рд╛рдИ рдврд┐рд▓реЛ рд░ рд╕реНрд░реЛрдд-рднреЛрдХреЛ рдмрдирд╛рдЙрдБрдЫ, рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЫрдиреН рд░ рдпреЛрдЬрдирд╛рдХреЛ рд╕рдВрд░рдЪрдирд╛ рд░ рдбреЗрдЯрд╛рдмрд╛рдЯ рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ.
рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдорд╛, рдкреНрд░рддреНрдпреЗрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛рд▓реЗ рдЖрдлреНрдиреЛ рдЕрдиреБрднрд╡рдорд╛ рдорд╛рддреНрд░ рднрд░ рдкрд░реНрджреИ рдЖрдлреИрдВрд▓реЗ рдЕрдкреНрдЯрд┐рдорд╛рдЗрдЬреЗрд╕рди рд╡рд┐рдХрд▓реНрдк рдЦреЛрдЬреНрдиреБ рдкрд░реНрджреИрди - рд╣рд╛рдореА рдЙрдиреАрд╣рд░реВрд▓рд╛рдИ рдпрд╣рд╛рдБ рдХреЗ рднрдЗрд░рд╣реЗрдХреЛ рдЫ, рдХрд╛рд░рдг рдХреЗ рд╣реБрди рд╕рдХреНрдЫ, рд░ рдмрддрд╛рдЙрди рд╕рдХреНрдЫреМрдВред рд╕рдорд╛рдзрд╛рди рдХрд╕рд░реА рдЦреЛрдЬреНрди рд╕рдХрд┐рдиреНрдЫ?ред рд╣рд╛рдореАрд▓реЗ рддреНрдпрд╣реА рдЧрд░реНрдпреМрдВред

рдпреА рдХреЗрд╕рд╣рд░реВрд▓рд╛рдИ рдирдЬрд┐рдХрдмрд╛рдЯ рд╣реЗрд░реМрдВтАФрдпрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдХрд╕рд░реА рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдиреНрдЫ рд░ рддрд┐рдиреАрд╣рд░реВрд▓реЗ рдХрд╕реНрддрд╛ рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВрддрд░реНрдл рдбреЛрд▒реНрдпрд╛рдЙрдЫрдиреНред
рд╡рд┐рд╖рдпрдорд╛ рд░рд╛рдореНрд░реЛрд╕рдБрдЧ рдбреБрдмреНрдирдХреЛ рд▓рд╛рдЧрд┐, рддрдкрд╛рдИрдВрд▓реЗ рдкрд╣рд┐рд▓реЗ рд╕рдореНрдмрдиреНрдзрд┐рдд рдмреНрд▓рдХ рд╕реБрдиреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ , рд░ рддреНрдпрд╕рдкрдЫрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЙрджрд╛рд╣рд░рдгрдХреЛ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╢реНрд▓реЗрд╖рдгрдорд╛ рдЬрд╛рдиреБрд╣реЛрд╕реН:

#рез: рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ "рдЕрдиреНрдбрд░рд╕рд░реНрдЯрд┐рдЩ"
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
"OOO Kolokolchik" рдЧреНрд░рд╛рд╣рдХрдХреЛ рд▓рд╛рдЧрд┐ рдкрдЫрд┐рд▓реНрд▓реЛ рдмреАрдЬрдХ рджреЗрдЦрд╛рдЙрдиреБрд╣реЛрд╕реНред
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> Limit
-> Sort
-> Index [Only] Scan [Backward] | Bitmap Heap Scan
рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХреЛ рд╕реВрдЪрдХрд╛рдВрдХ рдХреНрд░рдордмрджреНрдз рдХреНрд╖реЗрддреНрд░рд╣рд░реВ рд╕рд╣рд┐рдд рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрдиреБрд╣реЛрд╕реН.
рдЙрджрд╛рд╣рд░рдг:
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; 
рддрдкрд╛рдИрдВрд▓реЗ рддреБрд░реБрдиреНрддреИ рдпрд╛рдж рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдХрд┐ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдмрд╛рдЯ резрежреж рднрдиреНрджрд╛ рдмрдвреА рд░реЗрдХрд░реНрдбрд╣рд░реВ рдШрдЯрд╛рдЗрдПрдХрд╛ рдерд┐рдП, рдЬреБрди рд╕рдмреИ рдХреНрд░рдордмрджреНрдз рдЧрд░рд┐рдПрдХрд╛ рдерд┐рдП, рд░ рддреНрдпрд╕рдкрдЫрд┐ рдПрдЙрдЯрд╛ рдорд╛рддреНрд░ рдмрд╛рдБрдХреА рдерд┐рдпреЛред
рд╣рд╛рдореА рд╕рдорд╛рдзрд╛рди рдЧрд░реНрдЫреМрдВ:
DROP INDEX tbl_fk_cli_idx;
CREATE INDEX ON tbl(fk_cli, pk DESC); -- ╨┤╨╛╨▒╨░╨▓╨╕╨╗╨╕ ╨║╨╗╤О╤З ╤Б╨╛╤А╤В╨╕╤А╨╛╨▓╨║╨╕

рдпрд╕реНрддреЛ рдЖрджрд┐рдо рдирдореБрдирд╛ рд╣реБрдБрджрд╛ рдкрдирд┐ - рео.рел рдЧреБрдгрд╛ рдЫрд┐рдЯреЛ рд░ рейрей рдЧреБрдгрд╛ рдХрдо рдкрдардирдкреНрд░рддреНрдпреЗрдХ рдорд╛рдирдХреЛ рд▓рд╛рдЧрд┐ рддрдкрд╛рдИрдВрд╕рдБрдЧ рдЬрддрд┐ рдзреЗрд░реИ "рддрдереНрдпрд╣рд░реВ" рд╣реБрдиреНрдЫрдиреН, рдкреНрд░рднрд╛рд╡ рддреНрдпрддрд┐ рдиреИ рд╕реНрдкрд╖реНрдЯ рд╣реБрдиреЗрдЫред fk.
рдо рдпреЛ рдХреБрд░рд╛ рдпрд╛рдж рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреБ рдХрд┐ рдпрд╕реНрддреЛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рд▓реЗ "рдЙрдкрд╕рд░реНрдЧ" рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдХреЛ рд░реВрдкрдорд╛ рдХрд╛рдо рдЧрд░реНрдиреЗрдЫ рдЬреБрди рдЕрдиреНрдп рдкреНрд░рд╢реНрдирд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдЕрдШрд┐рд▓реНрд▓реЛ рднрдиреНрджрд╛ рдЦрд░рд╛рдм рд╣реБрдиреЗрдЫреИрдиред fk, рдЬрд╣рд╛рдБ рдХреНрд░рдордмрджреНрдз рдЧрд░реНрджреИ pk рдерд┐рдПрди рд░ рдЫреИрди (рддрдкрд╛рдИрдВ рдпрд╕ рдмрд╛рд░реЗ рдердк рдкрдвреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ) )ред рд╡рд┐рд╢реЗрд╖ рдЧрд░реА, рдпрд╕рд▓реЗ рд╕рд╛рдорд╛рдиреНрдп рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдЧрд░реНрдиреЗрдЫ рд╕реНрдкрд╖реНрдЯ рд╡рд┐рджреЗрд╢реА рдХреБрдЮреНрдЬреАрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рд╕рдорд░реНрдерди рдпрд╕ рдХреНрд╖реЗрддреНрд░рднрд░рд┐ред
#реи: рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди (рдмрд┐рдЯрдореНрдпрд╛рдкрдЕрдиреНрдб)
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
"NAO Lyutik" рдХреЛ рддрд░реНрдлрдмрд╛рдЯ рд╕рдореНрдкрдиреНрди рдЧреНрд░рд╛рд╣рдХ "OOO Kolokolchik" рдХреЛ рд▓рд╛рдЧрд┐ рд╕рдмреИ рд╕рдореНрдЭреМрддрд╛рд╣рд░реВ рджреЗрдЦрд╛рдЙрдиреБрд╣реЛрд╕реНред
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> 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); -- ╨╛╤В╨▒╨╛╤А ╨┐╨╛ ╨║╨╛╨╜╨║╤А╨╡╤В╨╜╨╛╨╣ ╨┐╨░╤А╨╡ 
рд╣рд╛рдореА рд╕рдорд╛рдзрд╛рди рдЧрд░реНрдЫреМрдВ:
DROP INDEX tbl_fk_org_idx;
CREATE INDEX ON tbl(fk_org, fk_cli);

рдпрд╣рд╛рдБ рд▓рд╛рдн рдХрдо рдЫ, рдХрд┐рдирдХрд┐ рдмрд┐рдЯрдореНрдпрд╛рдк рд╣рд┐рдк рд╕реНрдХреНрдпрд╛рди рдЖрдлреИрдВрдорд╛ рдзреЗрд░реИ рдкреНрд░рднрд╛рд╡рдХрд╛рд░реА рдЫред рддрд░ рдЕрдЭреИ рдкрдирд┐ рео.рел рдЧреБрдгрд╛ рдЫрд┐рдЯреЛ рд░ рейрей рдЧреБрдгрд╛ рдХрдо рдкрдарди.
#рей: рд╕рдВрдпреЛрдЬрди рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рд╣рд░реВ (BitmapOr)
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
рдкреНрд░рд╢реЛрдзрдирдХреЛ рд▓рд╛рдЧрд┐ рдкрд╣рд┐рд▓реЛ реиреж рдкреБрд░рд╛рдирд╛ "рдЖрдлреНрдиреИ" рд╡рд╛ рддреЛрдХрд┐рдПрдХрд╛ рдЕрдиреБрд░реЛрдзрд╣рд░реВ рджреЗрдЦрд╛рдЙрдиреБрд╣реЛрд╕реН, рдЬрд╕рдорд╛ рдЖрдлреНрдиреИ рдЕрдиреБрд░реЛрдзрд╣рд░реВ рдкреНрд░рд╛рдердорд┐рдХрддрд╛рдорд╛ рдкрд░реНрдиреЗрдЫрдиреНред
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> BitmapOr
-> Bitmap Index Scan
-> Bitmap Index Scanрд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
╨Ш╤Б╨┐╨╛╨╗╤М╨╖╨╛╨▓╨░╤В╤М рдпреБрдирд┐рдпрди [рд╕рдмреИ] рдкреНрд░рддреНрдпреЗрдХ OR рдмреНрд▓рдХ рд╕рд░реНрддрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдЙрдк-рдкреНрд░рд╢реНрдирд╣рд░реВ рд╕рдВрдпреЛрдЬрди рдЧрд░реНрдиред
рдЙрджрд╛рд╣рд░рдг:
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, ╨▒╨╛╨╗╤М╤И╨╡ ╨╕ ╨╜╨╡ ╨╜╨░╨┤╨╛ 
рд╣рд╛рдореАрд▓реЗ рдкрд╣рд┐рд▓реЛ рдмреНрд▓рдХрдорд╛ рд╕рдмреИ реиреж рдЖрд╡рд╢реНрдпрдХ рд░реЗрдХрд░реНрдбрд╣рд░реВ рддреБрд░реБрдиреНрддреИ рдкреНрд░рд╛рдкреНрдд рднрдПрдХреЛ рддрдереНрдпрдХреЛ рдлрд╛рдЗрджрд╛ рдЙрдард╛рдпреМрдВ, рддреНрдпрд╕реИрд▓реЗ рджреЛрд╕реНрд░реЛ, "рдорд╣рдБрдЧреЛ" рдмрд┐рдЯрдореНрдпрд╛рдк рд╣рд┐рдк рд╕реНрдХреНрдпрд╛рди рднрдПрдХреЛ, рдкрдирд┐ рдкреНрд░рджрд░реНрд╢рди рдЧрд░рд┐рдПрди - рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк реиреи рдЧреБрдгрд╛ рдЫрд┐рдЯреЛ, рекрек рдЧреБрдгрд╛ рдХрдо рдкрдарди!
рдпрд╕ рдЕрдиреБрдХреВрд▓рди рд╡рд┐рдзрд┐рдХреЛ рдердк рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИ рддрдкрд╛рдИрдВ рд▓реЗрдЦрд╣рд░реВрдорд╛ рдкрдвреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ ╨╕ .
рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рд╕рдВрд╕реНрдХрд░рдг рдзреЗрд░реИ рдХреБрдЮреНрдЬреАрд╣рд░реВрджреНрд╡рд╛рд░рд╛ рдХреНрд░рдордмрджреНрдз рдЪрдпрди (рд░ рдХреЗрд╡рд▓ const/NULL рдЬреЛрдбреАрдХреЛ рд▓рд╛рдЧрд┐ рдорд╛рддреНрд░ рд╣реЛрдЗрди) рд▓реЗрдЦрдорд╛ рдЫрд▓рдлрд▓ рдЧрд░рд┐рдПрдХреЛ рдЫ .
#рек: рд╣рд╛рдореА рдзреЗрд░реИ рдкрдвреНрдЫреМрдВ
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛, рдпреЛ рддрдм рд╣реБрдиреНрдЫ рдЬрдм рддрдкрд╛рдИрдВ рдЕрд╡рд╕реНрдерд┐рдд рдХреНрд╡реЗрд░реАрдорд╛ "рдЕрд░реНрдХреЛ рдлрд┐рд▓реНрдЯрд░ рдердкреНрди" рдЪрд╛рд╣рдиреБрд╣реБрдиреНрдЫред
"рд░ рддрдкрд╛рдИрдВрд╕рдБрдЧ рдкрдирд┐ рддреНрдпрд╕реНрддреИ рдЫреИрди, рддрд░ рдорджрд░-рдЕрдл-рдкрд░реНрд▓ рдмрдЯрдирд╣рд░реВ рд╕рд╣рд┐рдд? " рдлрд┐рдЪрд░ рдлрд┐рд▓реНрдо "рдж рдбрд╛рдпрдордВрдб рдЖрд░реНрдо"
рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдорд╛рдерд┐рдХреЛ рдХрд╛рд░реНрдпрд▓рд╛рдИ рдкрд░рд┐рдорд╛рд░реНрдЬрди рдЧрд░реНрджреИ рдкреНрд░рд╢реЛрдзрдирдХреЛ рд▓рд╛рдЧрд┐ рдкрд╣рд┐рд▓реЛ реиреж рдкреБрд░рд╛рдирд╛ "рдорд╣рддреНрд╡рдкреВрд░реНрдг" рдЕрдиреБрд░реЛрдзрд╣рд░реВ рджреЗрдЦрд╛рдЙрди, рддрд┐рдиреАрд╣рд░реВрдХреЛ рдЕрд╕рд╛рдЗрдирдореЗрдиреНрдЯ рдЬреЗрд╕реБрдХреИ рднрдП рдкрдирд┐ред
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& 5 ├Ч rows < RRbF -- ╨╛╤В╤Д╨╕╨╗╤М╤В╤А╨╛╨▓╨░╨╜╨╛ >80% ╨┐╤А╨╛╤З╨╕╤В╨░╨╜╨╜╨╛╨│╨╛
&& loops ├Ч RRbF > 100 -- ╨╕ ╨┐╤А╨╕ ╤Н╤В╨╛╨╝ ╨▒╨╛╨╗╤М╤И╨╡ 100 ╨╖╨░╨┐╨╕╤Б╨╡╨╣ ╤Б╤Г╨╝╨╝╨░╤А╨╜╨╛
рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
[рдердк] рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН WHERE рдЕрд╡рд╕реНрдерд╛ рднрдПрдХреЛ рд╕реВрдЪрдХрд╛рдВрдХ рд╡рд╛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдорд╛ рдердк рдХреНрд╖реЗрддреНрд░рд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрдиреБрд╣реЛрд╕реНред
рдпрджрд┐ рдлрд┐рд▓реНрдЯрд░ рдЕрд╡рд╕реНрдерд╛ рддрдкрд╛рдИрдВрдХреЛ рдХрд╛рд░реНрдпрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ "рд╕реНрдерд┐рд░" рдЫ рднрдиреЗ - рдЕрд░реНрдерд╛рддреН, рд╡рд┐рд╕реНрддрд╛рд░рд▓рд╛рдИ рдЬрдирд╛рдЙрдБрджреИрди рднрд╡рд┐рд╖реНрдпрдорд╛ рдорд╛рдирд╣рд░реВрдХреЛ рд╕реВрдЪреАрдХреЛ рд▓рд╛рдЧрд┐, WHERE рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБ рд░рд╛рдореНрд░реЛ рд╣реБрдиреНрдЫред рд╡рд┐рднрд┐рдиреНрди рдмреБрд▓рд┐рдпрди/рдПрдирдо рд╕реНрдерд┐рддрд┐рд╣рд░реВ рдпрд╕ рд╢реНрд░реЗрдгреАрдорд╛ рд░рд╛рдореНрд░реЛрд╕рдБрдЧ рдлрд┐рдЯ рд╣реБрдиреНрдЫрдиреНред
рдпрджрд┐ рдирд┐рд╕реНрдкрдВрджрди рдЕрд╡рд╕реНрдерд╛ рдлрд░рдХ рдорд╛рди рд▓рд┐рди рд╕рдХреНрдЫ, рддреНрдпрд╕рдкрдЫрд┐ рдпреА рдХреНрд╖реЗрддреНрд░рд╣рд░реВрд╕рдБрдЧ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрдиреБ рд░рд╛рдореНрд░реЛ рд╣реБрдиреНрдЫ - рдЬрд╕реНрддреИ рдорд╛рдерд┐рдХреЛ BitmapAnd рдХреЛ рдЕрд╡рд╕реНрдерд╛рдорд╛ред
рдЙрджрд╛рд╣рд░рдг:
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 INDEX ON tbl(pk)
WHERE critical; -- ╨┤╨╛╨▒╨░╨▓╨╕╨╗╨╕ "╤Б╤В╨░╤В╨╕╤З╨╜╨╛╨╡" ╤Г╤Б╨╗╨╛╨▓╨╕╨╡ ╤Д╨╕╨╗╤М╤В╤А╨░╤Ж╨╕╨╕

рд╣рд╛рдореА рджреЗрдЦреНрди рд╕рдХреНрдЫреМрдВ, рдпреЛрдЬрдирд╛рдмрд╛рдЯ рдлрд┐рд▓реНрдЯрд░рд┐рдЩ рдкреВрд░реНрдг рд░реВрдкрдорд╛ рдЧрд╛рдпрдм рднрдПрдХреЛ рдЫ, рд░ рдХреНрд╡реЗрд░реА рдмрдиреЗрдХреЛ рдЫ рел рдЧреБрдгрд╛ рдЫрд┐рдЯреЛ.
#рел: рд╕реНрдкрд░реНрд╕ рдЯреЗрдмрд▓
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
рдЯреЗрдмрд▓рдорд╛ рдзреЗрд░реИ рд╕рдВрдЦреНрдпрд╛рдорд╛ рд░реЗрдХрд░реНрдбрд╣рд░реВ рдЕрджреНрдпрд╛рд╡рдзрд┐рдХ/рдореЗрдЯрд╛рдЙрдБрджрд╛ рдареВрд▓реЛ рд╕рдВрдЦреНрдпрд╛рдорд╛ "рдореГрдд" рд░реЗрдХрд░реНрдбрд╣рд░реВрдХреЛ рд╕реНрдерд┐рддрд┐ рдирд┐рдореНрддреНрдпрд╛рдЙрдБрджрд╛ рдЕрдиреБрдХреВрд▓рди рдХрд╛рд░реНрдп рдкреНрд░рд╢реЛрдзрди рдХреНрдпреБ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреЗ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдпрд╛рд╕рд╣рд░реВред
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& loops ├Ч (rows + RRbF) < (shared hit + shared read) ├Ч 8
-- ╨┐╤А╨╛╤З╨╕╤В╨░╨╜╨╛ ╨▒╨╛╨╗╤М╤И╨╡ 1KB ╨╜╨░ ╨║╨░╨╢╨┤╤Г╤О ╨╖╨░╨┐╨╕╤Б╤М
&& shared hit + shared read > 64
рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
рдпрд╕рд▓рд╛рдИ рдирд┐рдпрдорд┐рдд рд░реВрдкрдорд╛ рдореНрдпрд╛рдиреБрдЕрд▓ рд░реВрдкрдорд╛ рд╕рдЮреНрдЪрд╛рд▓рди рдЧрд░реНрдиреБрд╣реЛрд╕реН рднреНрдпрд╛рдХреБрдо [рдкреВрд░реНрдг] рд╡рд╛ рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдкрдорд╛ рдмрд╛рд░рдореНрдмрд╛рд░ рдкреНрд░рд╢реЛрдзрди рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреБрд╣реЛрд╕реН рдпрд╕рдХреЛ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рдлрд╛рдЗрди-рдЯреНрдпреБрди рдЧрд░реЗрд░, рд╕рд╣рд┐рдд .
рдзреЗрд░реИрдЬрд╕реЛ рдЕрд╡рд╕реНрдерд╛рдорд╛, рдпрд╕реНрддрд╛ рд╕рдорд╕реНрдпрд╛рд╣рд░реВ рд╡реНрдпрд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХрд▓рд╛рдИ рдХрд▓ рдЧрд░реНрджрд╛ рдЦрд░рд╛рдм рдХреНрд╡реЗрд░реА рд╕рдВрд░рдЪрдирд╛рдХреЛ рдХрд╛рд░рдгрд▓реЗ рдЧрд░реНрджрд╛ рд╣реБрдиреНрдЫрдиреН рдЬрд╕реНрддреИ рдорд╛ рдЫрд▓рдлрд▓ рдЧрд░рд┐рдПрдХрд╛ .
рддрд░ рдпреЛ рдмреБрдЭреНрдиреБ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдЫ рдХрд┐ рднреНрдпрд╛рдХреБрдо рдлреБрд▓рд▓реЗ рдкрдирд┐ рд╕рдзреИрдВ рдорджреНрджрдд рдирдЧрд░реНрди рд╕рдХреНрдЫред рддреНрдпрд╕реНрддрд╛ рдЕрд╡рд╕реНрдерд╛рд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐, рд▓реЗрдЦрдорд╛ рджрд┐рдЗрдПрдХреЛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдорд╕рдБрдЧ рдкрд░рд┐рдЪрд┐рдд рд╣реБрдиреБ рдЙрдЪрд┐рдд рд╣реБрдиреНрдЫред .
#рем: рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдХреЛ "рдмреАрдЪ" рдмрд╛рдЯ рдкрдврд╛рдЗ
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
рдпрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдЫ рдХрд┐ рд╣рд╛рдореАрд▓реЗ рдереЛрд░реИ рдкрдвреНрдпреМрдВ, рд░ рд╕рдмреИ рдХреБрд░рд╛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдЧрд░рд┐рдпреЛ, рд░ рдХреБрдиреИ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдлрд┐рд▓реНрдЯрд░ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдПрди - рддрд░ рд╣рд╛рдореАрд▓реЗ рдЕрдЭреИ рдкрдирд┐ рдЪрд╛рд╣реЗрдХреЛ рднрдиреНрджрд╛ рдзреЗрд░реИ рдкреГрд╖реНрдард╣рд░реВ рдкрдвреНрдпреМрдВред
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> Index [Only] Scan [Backward]
&& loops ├Ч (rows + RRbF) < (shared hit + shared read) ├Ч 8
-- ╨┐╤А╨╛╤З╨╕╤В╨░╨╜╨╛ ╨▒╨╛╨╗╤М╤И╨╡ 1KB ╨╜╨░ ╨║╨░╨╢╨┤╤Г╤О ╨╖╨░╨┐╨╕╤Б╤М
&& shared hit + shared read > 64
рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХреЛ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдХреЛ рд╕рдВрд░рдЪрдирд╛ рд░ рдХреНрд╡реЗрд░реАрдорд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░рд┐рдПрдХрд╛ рдореБрдЦреНрдп рдХреНрд╖реЗрддреНрд░рд╣рд░реВрд▓рд╛рдИ рдирдЬрд┐рдХрдмрд╛рдЯ рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН - рд╕рдореНрднрд╡рддрдГ, рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдХреЛ рднрд╛рдЧ рд╕реЗрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫреИрдиред рд╕рдореНрднрд╡рддрдГ, рддрдкрд╛рдИрдВрд▓реЗ рд╕рдорд╛рди рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрдкрд░реНрдиреЗрдЫ, рддрд░ рдЙрдкрд╕рд░реНрдЧ рдХреНрд╖реЗрддреНрд░рд╣рд░реВ рдмрд┐рдирд╛ рд╡рд╛ .
рдЙрджрд╛рд╣рд░рдг:
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; 
рд╕рдмреИ рдХреБрд░рд╛ рдареАрдХрдард╛рдХ рджреЗрдЦрд┐рдиреНрдЫ, рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдХреЛ рд╕рд╛рде рдкрдирд┐, рддрд░ рдпреЛ рдЕрд▓рд┐ рд╢рдВрдХрд╛рд╕реНрдкрдж рдЫ - рдкрдврд┐рдПрдХрд╛ реиреж рд░реЗрдХрд░реНрдбрд╣рд░реВ рдордзреНрдпреЗ рдкреНрд░рддреНрдпреЗрдХрдХреЛ рд▓рд╛рдЧрд┐, рек рдкреГрд╖реНрдардХреЛ рдбреЗрдЯрд╛ рдкрдвреНрдиреБ рдкрд░реНрдпреЛ, рдкреНрд░рддрд┐ рд░реЗрдХрд░реНрдб рейреи рдХреЗрдмреА - рдХреЗ рддреНрдпреЛ рдЕрд▓рд┐ рдзреЗрд░реИ рд╣реЛрдЗрди рд░? рд░ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдХреЛ рдирд╛рдо рдкрдирд┐ред tbl_fk_org_fk_cli_idx рд╕реЛрдЪреНрди рдмрд╛рдзреНрдп рдкрд╛рд░реНрдиреЗред
рд╣рд╛рдореА рд╕рдорд╛рдзрд╛рди рдЧрд░реНрдЫреМрдВ:
CREATE INDEX ON tbl(fk_cli); 
рдЕрдЪрд╛рдирдХ - резреж рдЧреБрдгрд╛ рдЫрд┐рдЯреЛ, рд░ рдкрдвреНрдирдХреЛ рд▓рд╛рдЧрд┐ рек рдЧреБрдгрд╛ рдХрдо!
рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рд╣рд░реВ рдХреБрд╢рд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреНрд░рдпреЛрдЧ рдирдЧрд░рд┐рдПрдХрд╛ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рд╣рд░реВрдХрд╛ рдЕрдиреНрдп рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рд▓реЗрдЦрдорд╛ рд╣реЗрд░реНрди рд╕рдХрд┐рдиреНрдЫред .
#рен: CTE ├Ч CTE
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
рдЕрдиреБрд░реЛрдзрдорд╛ "рдореЛрдЯреЛ" CTE рднрд░реНрддреА рдЧрд░рд┐рдпреЛ рд╡рд┐рднрд┐рдиреНрди рдЯреЗрдмрд▓рд╣рд░реВрдмрд╛рдЯ, рд░ рддреНрдпрд╕рдкрдЫрд┐ рддрд┐рдиреАрд╣рд░реВ рдмреАрдЪ рд╕рдореНрдмрдиреНрдз рдмрдирд╛рдЙрдиреЗ рдирд┐рд░реНрдгрдп рдЧрд░реЗрдВ JOIN.
рдпреЛ рдХреЗрд╕ v12 рдореБрдирд┐рдХрд╛ рд╕рдВрд╕реНрдХрд░рдгрд╣рд░реВ рд╡рд╛ рдЕрдиреБрд░реЛрдзрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рд╕рд╛рдиреНрджрд░реНрднрд┐рдХ рдЫ WITH MATERIALIZED.
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> CTE Scan
&& loops > 10
&& loops ├Ч (rows + RRbF) > 10000
-- ╤Б╨╗╨╕╤И╨║╨╛╨╝ ╨▒╨╛╨╗╤М╤И╨╛╨╡ ╨┤╨╡╨║╨░╤А╤В╨╛╨▓╨╛ ╨┐╤А╨╛╨╕╨╖╨▓╨╡╨┤╨╡╨╜╨╕╨╡ CTE
рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
рдЕрдиреБрд░реЛрдзрд▓рд╛рдИ рдзреНрдпрд╛рдирдкреВрд░реНрд╡рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЧрд░реНрдиреБрд╣реЛрд╕реН - рд░ ? рдпрджрд┐ рддреНрдпрд╕реЛ рд╣реЛ рднрдиреЗ, рддреНрдпрд╕реЛ рднрдП hstore/json рдорд╛ "рд╢рдмреНрджрдХреЛрд╢" рд▓рд╛рдЧреВ рдЧрд░реНрдиреБрд╣реЛрд╕реН рдорд╛ рд╡рд░реНрдгрди рдЧрд░рд┐рдПрдХреЛ рдореЛрдбреЗрд▓ рдЕрдиреБрд╕рд╛рд░ .
#рео: рдбрд┐рд╕реНрдХрдорд╛ рд╕реНрд╡реНрдпрд╛рдк рдЧрд░реНрдиреБрд╣реЛрд╕реН (рдЕрд╕реНрдерд╛рдпреА рд▓реЗрдЦрд┐рдПрдХреЛ)
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
рдареВрд▓реЛ рд╕рдВрдЦреНрдпрд╛рдорд╛ рд░реЗрдХрд░реНрдбрд╣рд░реВрдХреЛ рдПрдХ рдкрдЯрдХрдХреЛ рдкреНрд░рд╢реЛрдзрди (рдХреНрд░рдордмрджреНрдз рдЧрд░реНрдиреЗ рд╡рд╛ рдЕрджреНрд╡рд┐рддреАрдпреАрдХрд░рдг) рдпрд╕ рдЙрджреНрджреЗрд╢реНрдпрдХреЛ рд▓рд╛рдЧрд┐ рдЫреБрдЯреНрдпрд╛рдЗрдПрдХреЛ рдореЗрдореЛрд░реАрдорд╛ рдлрд┐рдЯ рд╣реБрдБрджреИрдиред
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> *
&& temp written > 0рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
рдпрджрд┐ рдЕрдкрд░реЗрд╢рдирд▓реЗ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрдХреЛ рдореЗрдореЛрд░реАрдХреЛ рдорд╛рддреНрд░рд╛ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рдХреЛ рд╕реЗрдЯ рдорд╛рдирднрдиреНрджрд╛ рдзреЗрд░реИ рдмрдвреА рдЫреИрди рднрдиреЗ , рдпреЛ рд╕рдорд╛рдпреЛрдЬрди рдЧрд░реНрди рд▓рд╛рдпрдХ рдЫред рддрдкрд╛рдИрдВ рдпрд╕рд▓рд╛рдИ рд╕рдмреИрдХреЛ рд▓рд╛рдЧрд┐ рдХрдиреНрдлрд┐рдЧрд░реЗрд╕рдирдорд╛ рддреБрд░реБрдиреНрддреИ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ, рд╡рд╛ рдорд╛рд░реНрдлрдд SET [LOCAL] рд╡рд┐рд╢реЗрд╖ рдЕрдиреБрд░реЛрдз/рд▓реЗрдирджреЗрдирдХреЛ рд▓рд╛рдЧрд┐ред
рдЙрджрд╛рд╣рд░рдг:
SHOW work_mem;
-- "16MB"
SELECT
random()
FROM
generate_series(1, 1000000)
ORDER BY
1; 
рд╣рд╛рдореА рд╕рдорд╛рдзрд╛рди рдЧрд░реНрдЫреМрдВ:
SET work_mem = '128MB'; -- ╨┐╨╡╤А╨╡╨┤ ╨▓╤Л╨┐╨╛╨╗╨╜╨╡╨╜╨╕╨╡╨╝ ╨╖╨░╨┐╤А╨╛╤Б╨░ 
рд╕реНрдкрд╖реНрдЯ рдХрд╛рд░рдгрд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐, рдпрджрд┐ рдбрд┐рд╕реНрдХ рд╕реНрдкреЗрд╕рдХреЛ рд╕рдЯреНрдЯрд╛ рдореЗрдореЛрд░реА рдорд╛рддреНрд░ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдпреЛ рднрдиреЗ, рдХреНрд╡реЗрд░реА рдзреЗрд░реИ рдЫрд┐рдЯреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реБрдиреЗрдЫред рдпрд╕рд▓реЗ HDD рдмрд╛рдЯ рдХреЗрд╣реА рднрд╛рд░ рдкрдирд┐ рдШрдЯрд╛рдЙрдБрдЫред
рддрд░ рд╣рд╛рдореАрд▓реЗ рдмреБрдЭреНрдиреБрдкрд░реНрдЫ рдХрд┐ рд╕рдзреИрдВ рдзреЗрд░реИ рдореЗрдореЛрд░реА рдЫреБрдЯреНрдпрд╛рдЙрди рдкрдирд┐ рд╕рдореНрднрд╡ рдЫреИрди - рд╕рдмреИрдХреЛ рд▓рд╛рдЧрд┐ рдкрд░реНрдпрд╛рдкреНрдд рд╣реБрдиреЗрдЫреИрдиред
#реп: рдкреБрд░рд╛рдиреЛ рддрдереНрдпрд╛рдЩреНрдХ
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
рддрд┐рдиреАрд╣рд░реВрд▓реЗ рдПрдХреИрдЪреЛрдЯрд┐ рдбрд╛рдЯрд╛рдмреЗрд╕рдорд╛ рдзреЗрд░реИ рдХреБрд░рд╛рд╣рд░реВ рдЦрдиреНрдпрд╛рдП, рддрд░ рддреНрдпрд╕рд▓рд╛рдИ рдЪрд▓рд╛рдЙрди рд╕рдордп рдкрд╛рдПрдирдиреНред ANALYZE.
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
&& ratio >> 10рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
рдЬреЗ рднрдП рдкрдирд┐ рдЧрд░реМрдВред ANALYZE.
рдпреЛ рдЕрд╡рд╕реНрдерд╛рд▓рд╛рдИ рдердк рд╡рд┐рд╕реНрддреГрддрдорд╛ рд╡рд░реНрдгрди рдЧрд░рд┐рдПрдХреЛ рдЫ .
#резреж: "рдХреЗрд╣реА рдЧрд▓рдд рднрдпреЛ"
рдпреЛ рдХрд╣рд┐рд▓реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдиреНрдЫ?
рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рдЕрдиреБрд░реЛрдзрджреНрд╡рд╛рд░рд╛ рд▓рдЧрд╛рдЗрдПрдХреЛ рд▓рдХрдХреЛ рд▓рд╛рдЧрд┐ рдкрд░реНрдЦрдиреБ рдкрд░реЗрдХреЛ рдерд┐рдпреЛ, рд╡рд╛ рдЕрдкрд░реНрдпрд╛рдкреНрдд CPU/рд╣рд╛рдЗрдкрд░рднрд╛рдЗрдЬрд░ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рд╕реНрд░реЛрддрд╣рд░реВ рдерд┐рдПред
рдХрд╕рд░реА рдкрд╣рд┐рдЪрд╛рди рдЧрд░реНрдиреЗ
-> *
&& (shared hit / 8K) + (shared read / 1K) < time / 1000
-- RAM hit = 64MB/s, HDD read = 8MB/s
&& time > 100ms -- ╤З╨╕╤В╨░╨╗╨╕ ╨╝╨░╨╗╨╛, ╨╜╨╛ ╤Б╨╗╨╕╤И╨║╨╛╨╝ ╨┤╨╛╨╗╨│╨╛
рд╕рд┐рдлрд╛рд░рд┐рд╕рд╣рд░реВ
рдмрд╛рд╣реНрдп рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрд╣реЛрд╕реН рдЕрдиреБрдЧрдорди рдкреНрд░рдгрд╛рд▓реА рдЕрд╡рд░реЛрдз рд╡рд╛ рдЕрд╕рд╛рдорд╛рдиреНрдп рд╕реНрд░реЛрдд рдЦрдкрддрдХреЛ рд▓рд╛рдЧрд┐ рд╕рд░реНрднрд░рд╣рд░реВред рд╣рд╛рдореАрд▓реЗ рд╕рдпреМрдВ рд╕рд░реНрднрд░рд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдпреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдЧрд░реНрдиреЗ рд╣рд╛рдореНрд░реЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд╣рд┐рд▓реЗ рдиреИ рд╡рд░реНрдгрди рдЧрд░рд┐рд╕рдХреЗрдХрд╛ рдЫреМрдВред ╨╕ .


рд╕реНрд░реЛрдд: www.habr.com
