เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ

เดฎเดพเดธเด‚ เดฎเตเดฎเตเดชเต เดžเด™เตเด™เตพ เดชเตเดฐเด–เตเดฏเดพเดชเดฟเดšเตเดšเต เดตเดฟเดถเดฆเต€เด•เดฐเดฟเด•เตเด•เตเด•.tensor.ru - เดชเตŠเดคเต เด…เดจเตเดตเต‡เดทเดฃ เดชเตเดฒเดพเดจเตเด•เตพ เดชเดพเดดเตโ€Œเดธเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเด‚ เดฆเตƒเดถเตเดฏเดตเตฝเด•เตเด•เดฐเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดฎเตเดณเตเดณ เดธเต‡เดตเดจเด‚ PostgreSQL-เดฒเต‡เด•เตเด•เต.

เดจเดฟเด™เตเด™เตพ เด‡เดคเต เด‡เดคเดฟเดจเด•เด‚ 6000-เดฒเดงเดฟเด•เด‚ เดคเดตเดฃ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต, เดŽเดจเตเดจเดพเตฝ เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เดชเตเดชเต†เดŸเดพเดคเต† เดชเต‹เดฏเต‡เด•เตเด•เดพเดตเตเดจเตเดจ เด’เดฐเต เดนเดพเตปเดกเดฟ เดซเต€เดšเตเดšเตผ เด˜เดŸเดจเดพเดชเดฐเดฎเดพเดฏ เดธเต‚เดšเดจเด•เตพ, เด‡เดคเต เด‡เดคเตเดชเต‹เดฒเต† เด•เดพเดฃเดชเตเดชเต†เดŸเตเดจเตเดจเต:

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ

เด…เดต เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เตเด•, เดจเดฟเด™เตเด™เดณเตเดŸเต† เด…เดญเตเดฏเตผเดคเตเดฅเดจเด•เตพ "เดฎเดฟเดจเตเดธเดฎเดพเตผเดจเตเดจเดคเตเด‚ เดธเดฟเตฝเด•เตเด•เดฟ เด†เดฏเดฟ เดฎเดพเดฑเตเด‚." ๐Ÿ™‚

เดŽเดจเตเดจเดพเตฝ เด—เต—เดฐเดตเดฎเดพเดฏเดฟ, เด’เดฐเต เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดฎเดจเตเดฆเด—เดคเดฟเดฏเดฟเดฒเดพเด•เตเด•เตเดจเตเดจเดคเตเด‚ เดตเดฟเดญเดต-เดฆเดพเดนเด‚ เด‰เดฃเตเดŸเดพเด•เตเด•เตเดจเตเดจเดคเตเดฎเดพเดฏ เดชเดฒ เดธเดพเดนเดšเดฐเตเดฏเด™เตเด™เดณเตเด‚ เดธเดพเดงเดพเดฐเดฃเดตเตเด‚ เดชเตเดฒเดพเดจเดฟเดจเตเดฑเต† เด˜เดŸเดจเดฏเตเด‚ เดกเดพเดฑเตเดฑเดฏเตเด‚ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเตป เด•เดดเดฟเดฏเตเด‚.

เดˆ เดธเดพเดนเดšเดฐเตเดฏเดคเตเดคเดฟเตฝ, เด“เดฐเต‹ เดตเตเดฏเด•เตเดคเดฟเด—เดค เดกเต†เดตเดฒเดชเตเดชเตผเด•เตเด•เตเด‚ เดธเตเดตเดจเตเดคเด‚ เด…เดจเตเดญเดตเดคเตเดคเต† เดฎเดพเดคเตเดฐเด‚ เด†เดถเตเดฐเดฏเดฟเดšเตเดšเต เด’เดฐเต เด’เดชเตเดฑเตเดฑเดฟเดฎเตˆเดธเต‡เดทเตป เด“เดชเตเดทเตป เดจเต‹เด•เตเด•เต‡เดฃเตเดŸเดคเดฟเดฒเตเดฒ - เด‡เดตเดฟเดŸเต† เดŽเดจเตเดคเดพเดฃเต เดธเด‚เดญเดตเดฟเด•เตเด•เตเดจเตเดจเดคเต†เดจเตเดจเต เดจเดฎเตเด•เตเด•เต เด…เดตเดจเต‹เดŸเต เดชเดฑเดฏเดพเตป เด•เดดเดฟเดฏเตเด‚, เด•เดพเดฐเดฃเด‚ เดŽเดจเตเดคเดพเดฏเดฟเดฐเดฟเด•เตเด•เดพเด‚, เด•เต‚เดŸเดพเดคเต† เด’เดฐเต เดชเดฐเดฟเดนเดพเดฐเดคเตเดคเต† เดŽเด™เตเด™เดจเต† เดธเดฎเต€เดชเดฟเด•เตเด•เดพเด‚. เด…เดคเดพเดฃเต เดžเด™เตเด™เตพ เดšเต†เดฏเตเดคเดคเต.

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ

เดˆ เด•เต‡เดธเตเด•เตพ เดจเดฎเตเด•เตเด•เต เดธเต‚เด•เตเดทเตเดฎเดฎเดพเดฏเดฟ เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เดพเด‚ - เด…เดต เดŽเด™เตเด™เดจเต† เดจเดฟเตผเดตเดšเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดจเตเดจเต, เด…เดต เดŽเดจเตเดคเต เดถเตเดชเดพเตผเดถเด•เดณเดฟเดฒเต‡เด•เตเด•เต เดจเดฏเดฟเด•เตเด•เตเดจเตเดจเต.

เดตเดฟเดทเดฏเดคเตเดคเดฟเตฝ เดจเดจเตเดจเดพเดฏเดฟ เดฎเตเดดเตเด•เตเดจเตเดจเดคเดฟเดจเต, เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด†เดฆเตเดฏเด‚ เดฌเดจเตเดงเดชเตเดชเต†เดŸเตเดŸ เดฌเตเดฒเต‹เด•เตเด•เต เด•เต‡เตพเด•เตเด•เดพเด‚ PGConf.Russia 2020-เดฒเต† เดŽเดจเตเดฑเต† เดฑเดฟเดชเตเดชเต‹เตผเดŸเตเดŸเต, เด…เดคเดฟเดจเตเดถเต‡เดทเด‚ เดฎเดพเดคเตเดฐเดฎเต‡ เด“เดฐเต‹ เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเตเดฑเต†เดฏเตเด‚ เดตเดฟเดถเดฆเดฎเดพเดฏ เดตเดฟเดถเด•เดฒเดจเดคเตเดคเดฟเดฒเต‡เด•เตเด•เต เดจเต€เด™เตเด™เตเด•:

#1: เดธเต‚เดšเดฟเด• "เด…เดฃเตเดŸเตผเดธเต‹เตผเดŸเตเดŸเดฟเด‚เด—เต"

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

"LLC 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;

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดธเต‚เดšเดฟเด•เดฏเดฟเตฝ เดจเดฟเดจเตเดจเต 100-เดฒเดงเดฟเด•เด‚ เดฑเต†เด•เตเด•เต‹เตผเดกเตเด•เตพ เด•เตเดฑเดšเตเดšเดคเดพเดฏเดฟ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด‰เดŸเดจเดŸเดฟ เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เดพเดจเดพเด•เตเด‚, เด…เดตเดฏเต†เดฒเตเดฒเดพเด‚ เด•เตเดฐเดฎเต€เด•เดฐเดฟเดšเตเดšเต, เดคเตเดŸเตผเดจเตเดจเต เด…เดตเดถเต‡เดทเดฟเดšเตเดšเดคเต.

เดคเดฟเดฐเตเดคเตเดคเตเดจเตเดจเต:

DROP INDEX tbl_fk_cli_idx;
CREATE INDEX ON tbl(fk_cli, pk DESC); -- ะดะพะฑะฐะฒะธะปะธ ะบะปัŽั‡ ัะพั€ั‚ะธั€ะพะฒะบะธ

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เด…เดคเตเดคเดฐเดฎเตŠเดฐเต เดชเตเดฐเดพเด•เตƒเดค เดฎเดพเดคเตƒเด•เดฏเดฟเตฝ เดชเต‹เดฒเตเด‚ - 8.5 เดฎเดŸเด™เตเด™เต เดตเต‡เด—เดคเดฏเตเด‚ 33 เดฎเดŸเด™เตเด™เต เด•เตเดฑเดตเต เดตเดพเดฏเดจเดฏเตเด‚. เด“เดฐเต‹ เดฎเต‚เดฒเตเดฏเดคเตเดคเดฟเดจเตเด‚ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด•เต‚เดŸเตเดคเตฝ "เดตเดธเตเดคเตเดคเด•เตพ" เด‰เดฃเตเดŸเต, เด•เต‚เดŸเตเดคเตฝ เดตเตเดฏเด•เตเดคเดฎเดพเดฏ เดชเตเดฐเดญเดพเดตเด‚ fk.

เด…เดคเตเดคเดฐเด‚ เด’เดฐเต เดธเต‚เดšเดฟเด• เดฎเดฑเตเดฑเต เดšเต‹เดฆเตเดฏเด™เตเด™เตพเด•เตเด•เต เดฎเตเดฎเตเดชเดคเตเดคเต‡เด•เตเด•เดพเตพ เดฎเต‹เดถเดฎเดฒเตเดฒเดพเดคเตเดค เด’เดฐเต "เดชเตเดฐเดฟเดซเดฟเด•เตเดธเต" เดธเต‚เดšเดฟเด•เดฏเดพเดฏเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดฎเต†เดจเตเดจเต เดžเดพเตป เดถเตเดฐเดฆเตเดงเดฟเด•เตเด•เตเดจเตเดจเต. fk, เดŽเดตเดฟเดŸเต† เด…เดŸเตเด•เตเด•เตเด• pk เด‰เดฃเตเดŸเดพเดฏเดฟเดฐเตเดจเตเดจเดฟเดฒเตเดฒ, เด‡เดฒเตเดฒ (เด‡เดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด•เต‚เดŸเตเดคเตฝ เดตเดพเดฏเดฟเด•เตเด•เดพเด‚ เดซเดฒเดชเตเดฐเดฆเดฎเดฒเตเดฒเดพเดคเตเดค เดธเต‚เดšเดฟเด•เด•เตพ เด•เดฃเตเดŸเต†เดคเตเดคเตเดจเตเดจเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดŽเดจเตเดฑเต† เดฒเต‡เด–เดจเดคเตเดคเดฟเตฝ). เด‰เตพเดชเตเดชเต†เดŸเต†, เด‡เดคเต เดธเดพเดงเดพเดฐเดฃ เดจเตฝเด•เตเด‚ เดตเตเดฏเด•เตเดคเดฎเดพเดฏ เดตเดฟเดฆเต‡เดถ เด•เต€ เดชเดฟเดจเตเดคเตเดฃ เดˆ เดตเดฏเดฒเดฟเตฝ.

#2: เดธเต‚เดšเดฟเด• เด•เดตเดฒ (เดฌเดฟเดฑเตเดฑเตเดฎเดพเดชเตเดชเต เด†เตปเดกเต)

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

"NAO เดฌเดŸเตเดŸเตผเด•เดชเตเดชเดฟเดจเต" เดตเต‡เดฃเตเดŸเดฟ เดธเดฎเดพเดชเดฟเดšเตเดš "LLC 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); -- ะพั‚ะฑะพั€ ะฟะพ ะบะพะฝะบั€ะตั‚ะฝะพะน ะฟะฐั€ะต

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดคเดฟเดฐเตเดคเตเดคเตเดจเตเดจเต:

DROP INDEX tbl_fk_org_idx;
CREATE INDEX ON tbl(fk_org, fk_cli);

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดฌเดฟเดฑเตเดฑเตโ€Œเดฎเดพเดชเตเดชเต เดนเต€เดชเตเดชเต เดธเตเด•เดพเตป เดธเตเดตเดจเตเดคเดฎเดพเดฏเดฟ เดซเดฒเดชเตเดฐเดฆเดฎเดพเด•เตเดฎเต†เดจเตเดจเดคเดฟเดจเดพเตฝ เด‡เดตเดฟเดŸเต† เดชเตเดฐเดคเดฟเดซเดฒเด‚ เดšเต†เดฑเตเดคเดพเดฃเต. เดŽเดจเตเดจเดพเตฝ เดŽเดจเตเดคเดพเดฏเดพเดฒเตเด‚ 7 เดฎเดŸเด™เตเด™เต เดตเต‡เด—เดคเดฏเตเด‚ 2.5 เดฎเดŸเด™เตเด™เต เด•เตเดฑเดตเต เดตเดพเดฏเดจเดฏเตเด‚.

#3: เดธเต‚เดšเดฟเด•เด•เตพ เดฒเดฏเดฟเดชเตเดชเดฟเด•เตเด•เตเด• (BitmapOr)

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

เดจเดฟเด™เตเด™เดณเตเดŸเต‡เดคเต เดฎเตเตปเด—เดฃเดจเดฏเดฟเตฝ, เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เดฟเดจเดพเดฏเดฟ เดเดฑเตเดฑเดตเตเด‚ เดชเดดเดฏ 20 "เดžเด™เตเด™เตพ" เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เด…เดธเตˆเตป เดšเต†เดฏเตเดฏเดพเดคเตเดค เด…เดญเตเดฏเตผเดคเตเดฅเดจเด•เตพ เด•เดพเดฃเดฟเด•เตเด•เตเด•.

เดŽเด™เตเด™เดจเต† เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเด‚

-> 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;

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดคเดฟเดฐเตเดคเตเดคเตเดจเตเดจเต:

(
  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, ะฑะพะปัŒัˆะต ะธ ะฝะต ะฝะฐะดะพ

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เด†เดตเดถเตเดฏเดฎเดพเดฏ เดŽเดฒเตเดฒเดพ 20 เดฑเต†เด•เตเด•เต‹เตผเดกเตเด•เดณเตเด‚ เด†เดฆเตเดฏ เดฌเตเดฒเต‹เด•เตเด•เดฟเตฝ เด‰เดŸเดจเดŸเดฟ เดฒเดญเดฟเดšเตเดšเต เดŽเดจเตเดจ เดตเดธเตเดคเตเดค เดžเด™เตเด™เตพ เดชเตเดฐเดฏเต‹เดœเดจเดชเตเดชเต†เดŸเตเดคเตเดคเดฟ, เด…เดคเดฟเดจเดพเตฝ เดฐเดฃเตเดŸเดพเดฎเดคเตเดคเต‡เดคเต, เด•เต‚เดŸเตเดคเตฝ โ€œเดตเดฟเดฒเดฏเต‡เดฑเดฟเดฏโ€ เดฌเดฟเดฑเตเดฑเตเดฎเดพเดชเตเดชเต เดนเต€เดชเตเดชเต เดธเตเด•เดพเตป เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต, เดŽเด•เตเดธเดฟเด•เตเดฏเต‚เดŸเตเดŸเต เดšเต†เดฏเตเดคเดฟเดฒเตเดฒ - เด…เดตเดธเดพเดจเด‚ 22 เดฎเดŸเด™เตเด™เต เดตเต‡เด—เดคเตเดคเดฟเตฝ, 44 เดฎเดŸเด™เตเด™เต เด•เตเดฑเดตเต เดตเดพเดฏเดจเด•เตพ!

เดˆ เด’เดชเตเดฑเตเดฑเดฟเดฎเตˆเดธเต‡เดทเตป เดฐเต€เดคเดฟเดฏเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เด•เต‚เดŸเตเดคเตฝ เดตเดฟเดถเดฆเดฎเดพเดฏ เด•เดฅ เดจเดฟเตผเดฆเตเดฆเดฟเดทเตเดŸ เด‰เดฆเดพเดนเดฐเดฃเด™เตเด™เตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดฒเต‡เด–เดจเด™เตเด™เดณเดฟเตฝ เดตเดพเดฏเดฟเด•เตเด•เดพเด‚ PostgreSQL เด†เดจเตเดฑเดฟเดชเดพเดฑเตเดฑเต‡เดฃเตเด•เตพ: เดนเดพเดจเดฟเด•เดฐเดฎเดพเดฏ เดœเต‹เดฏเดฟเดจเตเด•เดณเตเด‚ OR-เด•เดณเตเด‚ ะธ PostgreSQL เด†เดจเตเดฑเดฟเดชเดพเดฑเตเดฑเต‡เดฃเตเด•เตพ: เดชเต‡เดฐเดฟเดจเดพเตฝ เดคเดฟเดฐเดฏเดฒเดฟเดจเตเดฑเต† เด†เดตเตผเดคเตเดคเดจ เดชเดฐเดฟเดทเตเด•เดฐเดฃเดคเตเดคเดฟเดจเตเดฑเต† เด’เดฐเต เด•เดฅ, เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ "เด…เด™เตเด™เต‹เดŸเตเดŸเตเด‚ เด‡เด™เตเด™เต‹เดŸเตเดŸเตเด‚ เด’เดชเตเดฑเตเดฑเดฟเดฎเตˆเดธเต‡เดทเตป".

เดชเตŠเดคเตเดตเดพเดฏ เดชเดคเดฟเดชเตเดชเต เดจเดฟเดฐเดตเดงเดฟ เด•เต€เด•เตพ เด…เดŸเดฟเดธเตเดฅเดพเดจเดฎเดพเด•เตเด•เดฟเดฏเตเดณเตเดณ เดคเดฟเดฐเดžเตเดžเต†เดŸเตเดชเตเดชเต เด“เตผเดกเตผ เดšเต†เดฏเตเดคเต (เด’เดชเตเดชเด‚ const/NULL เดœเต‹เดกเดฟ เดฎเดพเดคเตเดฐเดฎเดฒเตเดฒ) เดฒเต‡เด–เดจเดคเตเดคเดฟเตฝ เดšเตผเดšเตเดšเดšเต†เดฏเตเดฏเตเดจเตเดจเต SQL เดŽเด™เตเด™เดจเต†: เดšเต‹เดฆเตเดฏเดคเตเดคเดฟเตฝ เดจเต‡เดฐเดฟเดŸเตเดŸเต เด’เดฐเต เดฒเต‚เดชเตเดชเต เดŽเดดเตเดคเตเด•, เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ "เดŽเดฒเดฟเดฎเต†เดจเตเดฑเดฑเดฟ เดคเตเดฐเต€-เดธเตเดฑเตเดฑเต†เดชเตเดชเต".

#4: เดจเดฎเตเดฎเตพ เด…เดจเดพเดตเดถเตเดฏเดฎเดพเดฏ เด’เดฐเตเดชเดพเดŸเต เด•เดพเดฐเตเดฏเด™เตเด™เตพ เดตเดพเดฏเดฟเด•เตเด•เตเดจเตเดจเต

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

เด’เดฐเต เดšเดŸเตเดŸเด‚ เดชเต‹เดฒเต†, เด‡เดคเดฟเดจเด•เด‚ เดจเดฟเดฒเดตเดฟเดฒเตเดณเตเดณ เด’เดฐเต เด…เดญเตเดฏเตผเดคเตเดฅเดจเดฏเดฟเดฒเต‡เด•เตเด•เต "เดฎเดฑเตเดฑเตŠเดฐเต เดซเดฟเตฝเดŸเตเดŸเตผ เด…เดฑเตเดฑเดพเดšเตเดšเตเดšเต†เดฏเตเดฏเดพเตป" เดจเดฟเด™เตเด™เตพ เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ เด…เดคเต เด‰เดฏเตผเดจเตเดจเตเดตเดฐเตเดจเตเดจเต.

โ€œเดจเดฟเด™เตเด™เตพเด•เตเด•เดฟเดฒเตเดฒ, เดชเด•เตเดทเต‡ เดฎเดฆเตผ เด“เดซเต เดชเต‡เตพ เดฌเดŸเตเดŸเดฃเตเด•เตพเด•เตเด•เตŠเดชเตเดชเด‚? เดธเดฟเดจเดฟเดฎ "เดฆเดฟ เดกเดฏเดฎเดฃเตเดŸเต เด†เด‚"

เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดฎเตเด•เดณเดฟเดฒเตเดณเตเดณ เดŸเดพเดธเตโ€Œเด•เต เดชเดฐเดฟเดทเตโ€Œเด•เตเด•เดฐเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดฒเต‚เดŸเต†, เด…เดตเดฏเตเดŸเต† เด‰เดฆเตเดฆเต‡เดถเตเดฏเด‚ เดชเดฐเดฟเด—เดฃเดฟเด•เตเด•เดพเดคเต† เดคเดจเตเดจเต† เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เดฟเดจเตเดณเตเดณ เดเดฑเตเดฑเดตเตเด‚ เดชเดดเดฏ 20 "เดจเดฟเตผเดฃเตเดฃเดพเดฏเด•" เด…เดญเตเดฏเตผเดคเตเดฅเดจเด•เตพ เด•เดพเดฃเดฟเด•เตเด•เตเด•.

เดŽเด™เตเด™เดจเต† เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเด‚

-> 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;

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดคเดฟเดฐเตเดคเตเดคเตเดจเตเดจเต:

CREATE INDEX ON tbl(pk)
  WHERE critical; -- ะดะพะฑะฐะฒะธะปะธ "ัั‚ะฐั‚ะธั‡ะฝะพะต" ัƒัะปะพะฒะธะต ั„ะธะปัŒั‚ั€ะฐั†ะธะธ

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด•เดพเดฃเดพเดจเดพเด•เตเดจเตเดจเดคเตเดชเต‹เดฒเต†, เดชเตเดฒเดพเดจเดฟเตฝ เดจเดฟเดจเตเดจเต เดซเดฟเตฝเดŸเตเดŸเดฑเดฟเด‚เด—เต เดชเต‚เตผเดฃเตเดฃเดฎเดพเดฏเตเด‚ เด…เดชเตเดฐเดคเตเดฏเด•เตเดทเดฎเดพเดฏเดฟ, เด…เดญเตเดฏเตผเดคเตเดฅเดจเดฏเดพเดฏเดฟ 5 เดฎเดŸเด™เตเด™เต เดตเต‡เด—เดคเตเดคเดฟเตฝ.

#5: เดตเดฟเดฐเดณเดฎเดพเดฏ เดชเดŸเตเดŸเดฟเด•

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

เดจเดฟเด™เตเด™เดณเตเดŸเต† เดธเตเดตเดจเตเดคเด‚ เดŸเดพเดธเตโ€Œเด•เต เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เต เด•เตเดฏเต‚ เดธเตƒเดทเตโ€ŒเดŸเดฟเด•เตเด•เดพเดจเตเดณเตเดณ เดตเดฟเดตเดฟเดง เดถเตเดฐเดฎเด™เตเด™เตพ, เดŸเต‡เดฌเดฟเดณเดฟเดฒเต† เดฑเต†เด•เตเด•เต‹เตผเดกเตเด•เดณเตเดŸเต† เด’เดฐเต เดตเดฒเดฟเดฏ เดธเด‚เด–เตเดฏ เด…เดชเตโ€Œเดกเต‡เดฑเตเดฑเตเด•เตพ / เด‡เดฒเตเดฒเดพเดคเดพเด•เตเด•เดฒเตเด•เตพ เด’เดฐเต เดตเดฒเดฟเดฏ เดธเด‚เด–เตเดฏ "เดกเต†เดกเต" เดฑเต†เด•เตเด•เต‹เตผเดกเตเด•เดณเตเดŸเต† เด…เดตเดธเตเดฅเดฏเดฟเดฒเต‡เด•เตเด•เต เดจเดฏเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ.

เดŽเด™เตเด™เดจเต† เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเด‚

-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
   && loops ร— (rows + RRbF) < (shared hit + shared read) ร— 8
      -- ะฟั€ะพั‡ะธั‚ะฐะฝะพ ะฑะพะปัŒัˆะต 1KB ะฝะฐ ะบะฐะถะดัƒัŽ ะทะฐะฟะธััŒ
   && shared hit + shared read > 64

เดถเตเดชเดพเตผเดถเด•เตพ

เดชเดคเดฟเดตเดพเดฏเดฟ เดธเตเดตเดฎเต‡เดงเดฏเดพ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตเด• เดตเดพเด•เตเดตเด‚ [เดชเต‚เตผเดฃเตเดฃเด‚] เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เดฎเดคเดฟเดฏเดพเดฏ เด‡เดŸเดฏเตเด•เตเด•เดฟเดŸเต†เดฏเตเดณเตเดณ เดชเดฐเดฟเดถเต€เดฒเดจเด‚ เดจเต‡เดŸเตเด• เด“เดŸเตเดŸเต‹เดตเดพเด•เตเดตเด‚ เด‰เตพเดชเตเดชเต†เดŸเต†, เด…เดคเดฟเดจเตเดฑเต† เดชเดพเดฐเดพเดฎเต€เดฑเตเดฑเดฑเตเด•เตพ เดจเดจเตเดจเดพเดฏเดฟ เดŸเตเดฏเต‚เตบ เดšเต†เดฏเตเดคเตเด•เตŠเดฃเตเดŸเต เด’เดฐเต เดชเตเดฐเดคเตเดฏเต‡เด• เดชเดŸเตเดŸเดฟเด•เดฏเตเด•เตเด•เดพเดฏเดฟ.

เดฎเดฟเด•เตเด• เด•เต‡เดธเตเด•เดณเดฟเดฒเตเด‚, เดšเตผเดšเตเดš เดšเต†เดฏเตเดคเดคเตเดชเต‹เดฒเตเดณเตเดณ เดฌเดฟเดธเดฟเดจเดธเตเดธเต เดฒเต‹เดœเดฟเด•เตเด•เดฟเตฝ เดจเดฟเดจเตเดจเต เดตเดฟเดณเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ เดฎเต‹เดถเด‚ เดšเต‹เดฆเตเดฏ เด•เต‹เดฎเตเดชเต‹เดธเดฟเดทเตป เดฎเต‚เดฒเดฎเดพเดฃเต เด‡เดคเตเดคเดฐเด‚ เดชเตเดฐเดถเตเดจเด™เตเด™เตพ เด‰เดฃเตเดŸเดพเด•เตเดจเตเดจเดคเต PostgreSQL เด†เดจเตเดฑเดฟเดชเดพเดฑเตเดฑเต‡เดฃเตเด•เตพ: "เดฎเดฐเดฟเดšเตเดšเดตเดฐเตเดŸเต†" เด•เต‚เดŸเตเดŸเดคเตเดคเดฟเดจเต†เดคเดฟเดฐเดพเดฏ เดชเต‹เดฐเดพเดŸเตเดŸเด‚.

เดŽเดจเตเดจเดพเตฝ VACUUM FULL เดชเต‹เดฒเตเด‚ เดŽเดฒเตเดฒเดพเดฏเตเดชเตเดชเต‹เดดเตเด‚ เดธเดนเดพเดฏเดฟเดšเตเดšเต‡เด•เตเด•เดฟเดฒเตเดฒ เดŽเดจเตเดจเต เดจเดฟเด™เตเด™เตพ เดฎเดจเดธเตเดธเดฟเดฒเดพเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต. เด…เดคเตเดคเดฐเด‚ เดธเดจเตเดฆเตผเดญเด™เตเด™เดณเดฟเตฝ, เดฒเต‡เด–เดจเดคเตเดคเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เด…เตฝเด—เต‹เดฐเดฟเดคเด‚ เดธเตเดตเดฏเด‚ เดชเดฐเดฟเดšเดฏเดชเตเดชเต†เดŸเตเดคเตเดคเตเดจเตเดจเดคเต เดฎเต‚เดฒเตเดฏเดตเดคเตเดคเดพเดฃเต DBA: เดตเดพเด•เตเดตเด‚ เดชเดฐเดพเดœเดฏเดชเตเดชเต†เดŸเตเดฎเตเดชเต‹เตพ, เดžเด™เตเด™เตพ เดฎเต‡เดถ เดธเตเดตเดฎเต‡เดงเดฏเดพ เดตเตƒเดคเตเดคเดฟเดฏเดพเด•เตเด•เตเดจเตเดจเต.

#6: เดธเต‚เดšเดฟเด•เดฏเตเดŸเต† "เดฎเดงเตเดฏเดคเตเดคเดฟเตฝ" เดจเดฟเดจเตเดจเต เดตเดพเดฏเดจ

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

เดžเด™เตเด™เตพ เด•เตเดฑเดšเตเดšเต เดตเดพเดฏเดฟเดšเตเดšเดคเดพเดฏเดฟ เดคเต‹เดจเตเดจเตเดจเตเดจเต, เดŽเดฒเตเดฒเดพเด‚ เดธเต‚เดšเดฟเด•เดฏเดฟเดฒเดพเด•เตเด•เดฟ, เดžเด™เตเด™เตพ เด†เดฐเต†เดฏเตเด‚ เด…เดงเดฟเด•เดฎเดพเดฏเดฟ เดซเดฟเตฝเดŸเตเดŸเตผ เดšเต†เดฏเตเดคเดฟเดŸเตเดŸเดฟเดฒเตเดฒ - เดŽเดจเตเดจเดฟเดŸเตเดŸเตเด‚ เดžเด™เตเด™เตพ เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดฒเตเด‚ เด•เต‚เดŸเตเดคเตฝ เดชเต‡เดœเตเด•เตพ เดžเด™เตเด™เตพ เดตเดพเดฏเดฟเด•เตเด•เตเดจเตเดจเต.

เดŽเด™เตเด™เดจเต† เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเด‚

-> 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;

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดธเต‚เดšเดฟเด• เด…เดจเตเดธเดฐเดฟเดšเตเดšเต เดชเต‹เดฒเตเด‚ เดŽเดฒเตเดฒเดพเด‚ เดถเดฐเดฟเดฏเดพเดฃเต†เดจเตเดจเต เดคเต‹เดจเตเดจเตเดจเตเดจเต, เดชเด•เตเดทเต‡ เด‡เดคเต เดŽเด™เตเด™เดจเต†เดฏเต†เด™เตเด•เดฟเดฒเตเด‚ เดธเด‚เดถเดฏเดพเดธเตเดชเดฆเดฎเดพเดฃเต - เดตเดพเดฏเดฟเด•เตเด•เตเดจเตเดจ 20 เดฑเต†เด•เตเด•เต‹เตผเดกเตเด•เดณเดฟเตฝ เด“เดฐเต‹เดจเตเดจเดฟเดจเตเด‚ เดžเด™เตเด™เตพเด•เตเด•เต 4 เดชเต‡เดœเต เดกเดพเดฑเตเดฑ เด•เตเดฑเดฏเตเด•เตเด•เต‡เดฃเตเดŸเดฟ เดตเดจเตเดจเต, เด’เดฐเต เดฑเต†เด•เตเด•เต‹เตผเดกเดฟเดจเต 32 เด•เต†เดฌเดฟ - เด…เดคเต เดงเตˆเดฐเตเดฏเดฎเดฒเตเดฒเต‡? เด’เดชเตเดชเด‚ เดธเต‚เดšเดฟเด• เดจเดพเดฎเดตเตเด‚ tbl_fk_org_fk_cli_idx เดšเดฟเดจเตเดคเต‡เดพเดฆเตเดฆเต€เดชเด•เดฎเดพเดฏ.

เดคเดฟเดฐเตเดคเตเดคเตเดจเตเดจเต:

CREATE INDEX ON tbl(fk_cli);

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดชเต†เดŸเตเดŸเต†เดจเตเดจเต - 10 เดฎเดŸเด™เตเด™เต เดตเต‡เด—เดคเตเดคเดฟเตฝ, เดตเดพเดฏเดฟเด•เตเด•เดพเตป 4 เดฎเดŸเด™เตเด™เต เด•เตเดฑเดตเต!

เดธเต‚เดšเดฟเด•เด•เดณเตเดŸเต† เดซเดฒเดชเตเดฐเดฆเดฎเดฒเตเดฒเดพเดคเตเดค เด‰เดชเดฏเต‹เด—เดคเตเดคเดฟเดจเตเดฑเต† เดธเดพเดนเดšเดฐเตเดฏเด™เตเด™เดณเตเดŸเต† เดฎเดฑเตเดฑเต เด‰เดฆเดพเดนเดฐเดฃเด™เตเด™เตพ เดฒเต‡เด–เดจเดคเตเดคเดฟเตฝ เด•เดพเดฃเดพเด‚ DBA: เด‰เดชเดฏเต‹เด—เดถเต‚เดจเตเดฏเดฎเดพเดฏ เดธเต‚เดšเดฟเด•เด•เตพ เด•เดฃเตเดŸเต†เดคเตเดคเตเดจเตเดจเต.

#7: CTE ร— CTE

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

เด…เดญเตเดฏเตผเดคเตเดฅเดจเดฏเดฟเตฝ "เด•เตŠเดดเตเดชเตเดชเต" CTE เดธเตเด•เต‹เตผ เดšเต†เดฏเตเดคเต เดตเตเดฏเดคเตเดฏเดธเตเดค เดชเดŸเตเดŸเดฟเด•เด•เดณเดฟเตฝ เดจเดฟเดจเตเดจเต, เดคเตเดŸเตผเดจเตเดจเต เด…เดตเดฏเตเด•เตเด•เดฟเดŸเดฏเดฟเตฝ เด…เดคเต เดšเต†เดฏเตเดฏเดพเตป เดคเต€เดฐเตเดฎเดพเดจเดฟเดšเตเดšเต JOIN.

เด•เต‡เดธเต v12-เดจเต เดคเดพเดดเต†เดฏเตเดณเตเดณ เดชเดคเดฟเดชเตเดชเตเด•เตพเด•เตเด•เต‹ โ€‹โ€‹เด…เดญเตเดฏเตผเดคเตเดฅเดจเด•เตพเด•เตเด•เต‹ โ€‹โ€‹เดชเตเดฐเดธเด•เตเดคเดฎเดพเดฃเต WITH MATERIALIZED.

เดŽเด™เตเด™เดจเต† เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเด‚

-> CTE Scan
   && loops > 10
   && loops ร— (rows + RRbF) > 10000
      -- ัะปะธัˆะบะพะผ ะฑะพะปัŒัˆะพะต ะดะตะบะฐั€ั‚ะพะฒะพ ะฟั€ะพะธะทะฒะตะดะตะฝะธะต CTE

เดถเตเดชเดพเตผเดถเด•เตพ

เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดถเตเดฐเดฆเตเดงเดพเดชเต‚เตผเดตเตเดตเด‚ เดตเดฟเดถเด•เดฒเดจเด‚ เดšเต†เดฏเตเดฏเตเด• - เด’เดชเตเดชเด‚ CTE เด•เตพ เด‡เดตเดฟเดŸเต† เด†เดตเดถเตเดฏเดฎเตเดฃเตเดŸเต‹?? เด…เดคเต† เดŽเด™เตเด•เดฟเตฝ hstore/json-เตฝ "เดจเดฟเด˜เดฃเตเดŸเต" เดชเตเดฐเดฏเต‹เด—เดฟเด•เตเด•เตเด• เดตเดฟเดตเดฐเดฟเดšเตเดš เดฎเต‹เดกเตฝ เด…เดจเตเดธเดฐเดฟเดšเตเดšเต PostgreSQL เด†เดจเตเดฑเดฟเดชเดพเดฑเตเดฑเต‡เดฃเตเด•เตพ: เดจเดฎเตเด•เตเด•เต เด’เดฐเต เดจเดฟเด˜เดฃเตเดŸเต เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด•เดจเดคเตเดค JOIN เด…เดŸเดฟเด•เตเด•เตเด•.

#8: เดกเดฟเดธเตเด•เดฟเดฒเต‡เด•เตเด•เต เดธเตเดตเดพเดชเตเดชเต เดšเต†เดฏเตเดฏเตเด• (เดŸเต†เด‚เดชเต เดŽเดดเตเดคเดฟเดฏเดคเต)

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

เดงเดพเดฐเดพเดณเด‚ เดฑเต†เด•เตเด•เต‹เตผเดกเตเด•เดณเตเดŸเต† เด’เดฑเตเดฑเดคเตเดคเดตเดฃ เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เต (เดธเต‹เตผเดŸเตเดŸเดฟเด‚เด—เต เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เด…เดฆเตเดตเดฟเดคเต€เดฏเดฎเดพเด•เตเด•เตฝ) เด‡เดคเดฟเดจเดพเดฏเดฟ เดจเต€เด•เตเด•เดฟเดตเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจ เดฎเต†เดฎเตเดฎเดฑเดฟเดฏเตเดฎเดพเดฏเดฟ เดชเตŠเดฐเตเดคเตเดคเดชเตเดชเต†เดŸเตเดจเตเดจเดฟเดฒเตเดฒ.

เดŽเด™เตเด™เดจเต† เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเด‚

-> *
   && temp written > 0

เดถเตเดชเดพเตผเดถเด•เตพ

เด“เดชเตเดชเดฑเต‡เดทเตป เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจ เดฎเต†เดฎเตเดฎเดฑเดฟเดฏเตเดŸเต† เด…เดณเดตเต เดชเดฐเดพเดฎเต€เดฑเตเดฑเดฑเดฟเดจเตเดฑเต† เดจเดฟเตผเดฆเตเดฆเดฟเดทเตเดŸ เดฎเต‚เดฒเตเดฏเดคเตเดคเต† เด•เดตเดฟเดฏเตเดจเตเดจเดฟเดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เดœเต‹เดฒเดฟ_เดฎเต†เด‚, เด…เดคเต เดคเดฟเดฐเตเดคเตเดคเตเดจเตเดจเดคเต เดฎเต‚เดฒเตเดฏเดตเดคเตเดคเดพเดฃเต. เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด‰เดŸเดจเดŸเดฟ เดŽเดฒเตเดฒเดพเดตเตผเด•เตเด•เตเดฎเดพเดฏเดฟ เด•เต‹เตบเดซเดฟเด—เดฑเดฟเดฒเต‡เด•เตเด•เต เดชเต‹เด•เดพเด‚, เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด•เดดเดฟเดฏเตเด‚ SET [LOCAL] เด’เดฐเต เดจเดฟเตผเดฆเตเดฆเดฟเดทเตเดŸ เด…เดญเตเดฏเตผเดคเตเดฅเดจ/เด‡เดŸเดชเดพเดŸเดฟเดจเต.

เด‰เดฆเดพเดนเดฐเดฃเด‚:

SHOW work_mem;
-- "16MB"

SELECT
  random()
FROM
  generate_series(1, 1000000)
ORDER BY
  1;

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดคเดฟเดฐเตเดคเตเดคเตเดจเตเดจเต:

SET work_mem = '128MB'; -- ะฟะตั€ะตะด ะฒั‹ะฟะพะปะฝะตะฝะธะตะผ ะทะฐะฟั€ะพัะฐ

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
[explain.tensor.ru-เตฝ เด•เดพเดฃเตเด•]

เดตเตเดฏเด•เตเดคเดฎเดพเดฏ เด•เดพเดฐเดฃเด™เตเด™เดณเดพเตฝ, เดกเดฟเดธเตเด•เดฒเตเดฒ เดฎเต†เดฎเตเดฎเดฑเดฟ เดฎเดพเดคเตเดฐเดฎเต‡ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเตเดณเตเดณเต‚ เดŽเด™เตเด•เดฟเตฝ, เดšเต‹เดฆเตเดฏเด‚ เดตเดณเดฐเต† เดตเต‡เด—เดคเตเดคเดฟเตฝ เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตเด‚. เด…เดคเต‡ เดธเดฎเดฏเด‚, เดŽเดšเตเดšเตเดกเดฟเดกเดฟเดฏเดฟเตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เดฒเต‹เดกเดฟเดจเตเดฑเต† เด’เดฐเต เดญเดพเด—เดตเตเด‚ เดจเต€เด•เตเด•เด‚เดšเต†เดฏเตเดฏเตเดจเตเดจเต.

เดŽเดจเตเดจเดพเตฝ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดŽเดฒเตเดฒเดพเดฏเตเดชเตเดชเต‹เดดเตเด‚ เดงเดพเดฐเดพเดณเด‚ เดฎเต†เดฎเตเดฎเดฑเดฟ เด…เดจเตเดตเดฆเดฟเด•เตเด•เดพเตป เด•เดดเดฟเดฏเดฟเดฒเตเดฒเต†เดจเตเดจเต เดจเดฟเด™เตเด™เตพ เดฎเดจเดธเตเดธเดฟเดฒเดพเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต - เดŽเดฒเตเดฒเดพเดตเตผเด•เตเด•เตเด‚ เดฎเดคเดฟเดฏเดพเด•เดฟเดฒเตเดฒ.

#9: เด…เดชเตเดฐเดธเด•เตเดคเดฎเดพเดฏ เดธเตเดฅเดฟเดคเดฟเดตเดฟเดตเดฐเด•เตเด•เดฃเด•เตเด•เตเด•เตพ

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

เด…เดตเตผ เด’เดฐเต‡เดธเดฎเดฏเด‚ เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเดฒเต‡เด•เตเด•เต เดงเดพเดฐเดพเดณเด‚ เดชเด•เตผเดจเตเดจเต, เดชเด•เตเดทเต‡ เด…เดคเต เด“เดŸเดฟเด•เตเด•เดพเตป เดธเดฎเดฏเดฎเดฟเดฒเตเดฒ ANALYZE.

เดŽเด™เตเด™เดจเต† เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเด‚

-> Seq Scan | Bitmap Heap Scan | Index [Only] Scan [Backward]
   && ratio >> 10

เดถเตเดชเดพเตผเดถเด•เตพ

เด…เดคเต เดจเดŸเดชเตเดชเดฟเดฒเดพเด•เตเด•เตเด• ANALYZE.

เดˆ เดธเดพเดนเดšเดฐเตเดฏเด‚ เด•เต‚เดŸเตเดคเตฝ เดตเดฟเดถเดฆเดฎเดพเดฏเดฟ เดตเดฟเดตเดฐเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต PostgreSQL เด†เดจเตเดฑเดฟเดชเดพเดฑเตเดฑเต‡เดฃเตเด•เตพ: เดธเตเดฅเดฟเดคเดฟเดตเดฟเดตเดฐเด•เตเด•เดฃเด•เตเด•เตเด•เดณเดพเดฃเต เดŽเดฒเตเดฒเดพเด‚.

#10: "เดŽเดจเตเดคเต‹ เด•เตเดดเดชเตเดชเด‚ เดธเด‚เดญเดตเดฟเดšเตเดšเต"

เดŽเดชเตเดชเต‹เตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเต

เด’เดฐเต เดฎเดคเตเดธเดฐเดพเดงเดฟเดทเตเด เดฟเดค เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดšเตเดฎเดคเตเดคเดฟเดฏ เดฒเต‹เด•เตเด•เดฟเดจเดพเดฏเดฟ เด’เดฐเต เด•เดพเดคเตเดคเดฟเดฐเดฟเดชเตเดชเตเดฃเตเดŸเดพเดฏเดฟเดฐเตเดจเตเดจเต, เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เดฎเดคเดฟเดฏเดพเดฏ CPU/เดนเตˆเดชเตเดชเตผเดตเตˆเดธเตผ เดนเดพเตผเดกเตโ€Œเดตเต†เดฏเตผ เด‰เดฑเดตเดฟเดŸเด™เตเด™เตพ เด‡เดฒเตเดฒเดพเดฏเดฟเดฐเตเดจเตเดจเต.

เดŽเด™เตเด™เดจเต† เดคเดฟเดฐเดฟเดšเตเดšเดฑเดฟเดฏเดพเด‚

-> *
   && (shared hit / 8K) + (shared read / 1K) < time / 1000
      -- RAM hit = 64MB/s, HDD read = 8MB/s
   && time > 100ms -- ั‡ะธั‚ะฐะปะธ ะผะฐะปะพ, ะฝะพ ัะปะธัˆะบะพะผ ะดะพะปะณะพ

เดถเตเดชเดพเตผเดถเด•เตพ

เดฌเดพเดนเตเดฏเดฎเดพเดฏเดฟ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเด• เดจเดฟเดฐเต€เด•เตเดทเดฃ เดธเด‚เดตเดฟเดงเดพเดจเด‚ เดคเดŸเดฏเตเดจเตเดจเดคเดฟเดจเต‹ เด…เดธเดพเดงเดพเดฐเดฃเดฎเดพเดฏ เดตเดฟเดญเดต เด‰เดชเดญเต‹เด—เดคเตเดคเดฟเดจเต‹ เด‰เดณเตเดณ เดธเต†เตผเดตเตผ. เดจเต‚เดฑเตเด•เดฃเด•เตเด•เดฟเดจเต เดธเต†เตผเดตเดฑเตเด•เตพเด•เตเด•เดพเดฏเดฟ เดˆ เดชเตเดฐเด•เตเดฐเดฟเดฏ เดธเด‚เด˜เดŸเดฟเดชเตเดชเดฟเด•เตเด•เตเดจเตเดจเดคเดฟเดจเตเดณเตเดณ เดžเด™เตเด™เดณเตเดŸเต† เดชเดคเดฟเดชเตเดชเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเต เดžเด™เตเด™เตพ เด‡เดคเดฟเดจเด•เด‚ เดธเด‚เดธเดพเดฐเดฟเดšเตเดšเต เด‡เดตเดฟเดŸเต† ะธ เด‡เดตเดฟเดŸเต†.

เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ
เด…เดธเตเด–เดฎเตเดณเตเดณ SQL เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เตพเด•เตเด•เตเดณเตเดณ เดชเดพเดšเด•เด•เตเด•เตเดฑเดฟเดชเตเดชเตเด•เตพ

เด…เดตเดฒเด‚เดฌเด‚: www.habr.com

เด’เดฐเต เด…เดญเดฟเดชเตเดฐเดพเดฏเด‚ เดšเต‡เตผเด•เตเด•เตเด•