āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ

āĻŽāĻžāĻ¸ āĻ•āĻ¤āĻ• āĻĒā§‚āĻ°ā§āĻŦā§‡ āĻ†āĻŽāĻ°āĻž āĻ˜ā§‹āĻˇāĻŖāĻž āĻ•āĻ°ā§‡āĻ›āĻŋ āĻŦā§āĻ¯āĻžāĻ–ā§āĻ¯āĻž.tensor.ru - āĻĒāĻžāĻŦāĻ˛āĻŋāĻ• āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻž āĻĒāĻžāĻ°ā§āĻ¸āĻŋāĻ‚ āĻāĻŦāĻ‚ āĻ­āĻŋāĻœā§āĻ¯ā§āĻ¯āĻŧāĻžāĻ˛āĻžāĻ‡āĻœ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻĒāĻ°āĻŋāĻˇā§‡āĻŦāĻž PostgreSQL āĻāĨ¤

āĻ†āĻĒāĻ¨āĻŋ āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻāĻŸāĻŋ 6000 āĻŦāĻžāĻ°ā§‡āĻ° āĻŦā§‡āĻļāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡āĻ›ā§‡āĻ¨, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ•āĻŸāĻŋ āĻ¸āĻšāĻœ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯ āĻ¯āĻž āĻ…āĻ˛āĻ•ā§āĻˇāĻŋāĻ¤ āĻšāĻ¯āĻŧā§‡ āĻĨāĻžāĻ•āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻ•āĻžāĻ āĻžāĻŽā§‹āĻ—āĻ¤ āĻ¸ā§‚āĻ¤ā§āĻ°, āĻ¯āĻž āĻĻā§‡āĻ–āĻ¤ā§‡ āĻāĻ‡āĻ°āĻ•āĻŽ āĻ•āĻŋāĻ›ā§:

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ

āĻ¤āĻžāĻĻā§‡āĻ° āĻ•āĻĨāĻž āĻļā§āĻ¨ā§āĻ¨ āĻāĻŦāĻ‚ āĻ†āĻĒāĻ¨āĻžāĻ° āĻ…āĻ¨ā§āĻ°ā§‹āĻ§āĻ—ā§āĻ˛āĻŋ "āĻŽāĻ¸ā§ƒāĻŖ āĻāĻŦāĻ‚ āĻ°ā§‡āĻļāĻŽā§€ āĻšāĻ¯āĻŧā§‡ āĻ‰āĻ āĻŦā§‡āĨ¤" 🙂

āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ—ā§āĻ°ā§āĻ¤ā§āĻŦ āĻ¸āĻšāĻ•āĻžāĻ°ā§‡, āĻ…āĻ¨ā§‡āĻ• āĻĒāĻ°āĻŋāĻ¸ā§āĻĨāĻŋāĻ¤āĻŋ āĻ¯āĻž āĻāĻ•āĻŸāĻŋ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻ§ā§€āĻ° āĻāĻŦāĻ‚ āĻ¸āĻŽā§āĻĒāĻĻ-āĻ•ā§āĻˇā§āĻ§āĻžāĻ°ā§āĻ¤ āĻ•āĻ°ā§‡ āĻ¤ā§‹āĻ˛ā§‡ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻāĻŦāĻ‚ āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻžāĻ° āĻ—āĻ āĻ¨ āĻāĻŦāĻ‚ āĻĄā§‡āĻŸāĻž āĻĻā§āĻŦāĻžāĻ°āĻž āĻ¸ā§āĻŦā§€āĻ•ā§ƒāĻ¤ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡.

āĻāĻ‡ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ¸ā§āĻŦāĻ¤āĻ¨ā§āĻ¤ā§āĻ° āĻŦāĻŋāĻ•āĻžāĻļāĻ•āĻžāĻ°ā§€āĻ•ā§‡ āĻ¤āĻžāĻ° āĻ¨āĻŋāĻœā§‡āĻ° āĻ…āĻ­āĻŋāĻœā§āĻžāĻ¤āĻžāĻ° āĻ‰āĻĒāĻ° āĻ¨āĻŋāĻ°ā§āĻ­āĻ° āĻ•āĻ°ā§‡ āĻ¨āĻŋāĻœā§‡āĻ° āĻĨā§‡āĻ•ā§‡ āĻāĻ•āĻŸāĻŋ āĻ…āĻĒā§āĻŸāĻŋāĻŽāĻžāĻ‡āĻœā§‡āĻļāĻ¨ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒā§‡āĻ° āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ āĻ¨āĻž - āĻ†āĻŽāĻ°āĻž āĻ¤āĻžāĻ•ā§‡ āĻŦāĻ˛āĻ¤ā§‡ āĻĒāĻžāĻ°āĻŋ āĻāĻ–āĻžāĻ¨ā§‡ āĻ•ā§€ āĻ˜āĻŸāĻ›ā§‡, āĻ•āĻžāĻ°āĻŖ āĻ•ā§€ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻāĻŦāĻ‚ āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻāĻ•āĻŸāĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§‡āĻ° āĻ•āĻžāĻ›ā§‡ āĻ¯ā§‡āĻ¤ā§‡ āĻšāĻ¯āĻŧ. āĻ¸ā§‡āĻŸāĻžāĻ‡ āĻ†āĻŽāĻ°āĻž āĻ•āĻ°ā§‡āĻ›āĻŋāĨ¤

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ

āĻ†āĻ¸ā§āĻ¨ āĻāĻ‡ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡āĻ—ā§āĻ˛āĻŋ āĻ˜āĻ¨āĻŋāĻˇā§āĻ āĻ­āĻžāĻŦā§‡ āĻĻā§‡āĻ–ā§‡ āĻ¨ā§‡āĻ“āĻ¯āĻŧāĻž āĻ¯āĻžāĻ• - āĻ•ā§€āĻ­āĻžāĻŦā§‡ āĻ¸ā§‡āĻ—ā§āĻ˛āĻŋ āĻ¸āĻ‚āĻœā§āĻžāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻ¤āĻžāĻ°āĻž āĻ•ā§€ āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ āĻ•āĻ°ā§‡āĨ¤

āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŸāĻŋāĻ¤ā§‡ āĻ¨āĻŋāĻœā§‡āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ­āĻžāĻ˛āĻ­āĻžāĻŦā§‡ āĻ¨āĻŋāĻŽāĻœā§āĻœāĻŋāĻ¤ āĻ•āĻ°āĻ¤ā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻĒā§āĻ°āĻĨāĻŽā§‡ āĻ¸āĻ‚āĻļā§āĻ˛āĻŋāĻˇā§āĻŸ āĻŦā§āĻ˛āĻ• āĻĨā§‡āĻ•ā§‡ āĻļā§āĻ¨āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ 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;

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻ†āĻĒāĻ¨āĻŋ āĻ…āĻŦāĻŋāĻ˛āĻŽā§āĻŦā§‡ āĻ˛āĻ•ā§āĻˇā§āĻ¯ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ āĻ¯ā§‡ āĻ¸ā§‚āĻšā§€ āĻĨā§‡āĻ•ā§‡ 100 āĻŸāĻŋāĻ°āĻ“ āĻŦā§‡āĻļāĻŋ āĻ°ā§‡āĻ•āĻ°ā§āĻĄ āĻŦāĻŋāĻ¯āĻŧā§‹āĻ— āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ¯ā§‡āĻ—ā§āĻ˛āĻŋ āĻ¤āĻžāĻ°āĻĒāĻ°ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¸āĻžāĻœāĻžāĻ¨ā§‹ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛ āĻāĻŦāĻ‚ āĻ¤āĻžāĻ°āĻĒāĻ°ā§‡ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻāĻ•āĻŸāĻŋ āĻŦāĻžāĻ•āĻŋ āĻ›āĻŋāĻ˛āĨ¤

āĻ¸āĻ‚āĻļā§‹āĻ§āĻ¨ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡:

DROP INDEX tbl_fk_cli_idx;
CREATE INDEX ON tbl(fk_cli, pk DESC); -- дОйавиĐģи ĐēĐģŅŽŅ‡ ŅĐžŅ€Ņ‚иŅ€ĐžĐ˛Đēи

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻāĻŽāĻ¨āĻ•āĻŋ āĻāĻŽāĻ¨ āĻāĻ•āĻŸāĻŋ āĻ†āĻĻāĻŋāĻŽ āĻ¨āĻŽā§āĻ¨āĻžāĻ° āĻ‰āĻĒāĻ°āĻ“ - 8.5 āĻ—ā§āĻŖ āĻĻā§āĻ°ā§āĻ¤ āĻāĻŦāĻ‚ 33 āĻ—ā§āĻŖ āĻ•āĻŽ āĻĒāĻĄāĻŧāĻž. āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻŽāĻžāĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ†āĻĒāĻ¨āĻžāĻ° āĻ•āĻžāĻ›ā§‡ āĻ¯āĻ¤ āĻŦā§‡āĻļāĻŋ "āĻ¤āĻĨā§āĻ¯" āĻĨāĻžāĻ•āĻŦā§‡, āĻĒā§āĻ°āĻ­āĻžāĻŦ āĻ¤āĻ¤ āĻŦā§‡āĻļāĻŋ āĻ¸ā§āĻĒāĻˇā§āĻŸ āĻšāĻŦā§‡ fk.

āĻ†āĻŽāĻŋ āĻŽāĻ¨ā§‡ āĻ•āĻ°āĻŋ āĻ¯ā§‡ āĻāĻ‡ āĻ§āĻ°āĻ¨ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ¸ā§‚āĻšāĻ• āĻāĻ•āĻŸāĻŋ "āĻĒā§āĻ°āĻŋāĻĢāĻŋāĻ•ā§āĻ¸" āĻ¸ā§‚āĻšāĻ• āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻ•āĻžāĻœ āĻ•āĻ°āĻŦā§‡ āĻ…āĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ†āĻ—ā§‡āĻ° āĻšā§‡āĻ¯āĻŧā§‡ āĻ–āĻžāĻ°āĻžāĻĒ āĻ¨āĻ¯āĻŧ fk, āĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ¸āĻžāĻœāĻžāĻ¨ pk āĻ¸ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ›āĻŋāĻ˛ āĻ¨āĻž āĻāĻŦāĻ‚ āĻ¨ā§‡āĻ‡ (āĻ†āĻĒāĻ¨āĻŋ āĻāĻŸāĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻĒāĻĄāĻŧāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ āĻ…āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻ¸ā§‚āĻšāĻ• āĻ–ā§‹āĻāĻœāĻžāĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧā§‡ āĻ†āĻŽāĻžāĻ° āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡) āĻ¸āĻš, āĻāĻŸāĻŋ āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ• āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻ•āĻ°āĻŦā§‡ āĻ¸ā§āĻ¸ā§āĻĒāĻˇā§āĻŸ āĻŦāĻŋāĻĻā§‡āĻļā§€ āĻ•ā§€ āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨ āĻāĻ‡ āĻŽāĻžāĻ ā§‡āĨ¤

#2: āĻ¸ā§‚āĻšāĻ• āĻ›ā§‡āĻĻ (āĻŦāĻŋāĻŸāĻŽā§āĻ¯āĻžāĻĒāĻāĻ¨ā§āĻĄ)

āĻ¯āĻ–āĻ¨ āĻ‰āĻĻāĻ¯āĻŧ āĻšāĻ¯āĻŧ

āĻ•ā§āĻ˛āĻžāĻ¯āĻŧā§‡āĻ¨ā§āĻŸ "LLC Kolokolchik" āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻšā§āĻ•ā§āĻ¤āĻŋ āĻĻā§‡āĻ–āĻžāĻ¨, "NAO Buttercup" āĻāĻ° āĻĒāĻ•ā§āĻˇā§‡ āĻ¸āĻŽāĻžāĻĒā§āĻ¤ā§ˇ

āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻ¸āĻ¨āĻžāĻ•ā§āĻ¤ āĻ•āĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ

-> 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); -- ĐžŅ‚йОŅ€ ĐŋĐž ĐēĐžĐŊĐēŅ€ĐĩŅ‚ĐŊОК ĐŋĐ°Ņ€Đĩ

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻ¸āĻ‚āĻļā§‹āĻ§āĻ¨ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡:

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

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻāĻ–āĻžāĻ¨ā§‡ āĻĒā§‡āĻ…āĻĢ āĻ•āĻŽ, āĻ¯ā§‡āĻšā§‡āĻ¤ā§ āĻŦāĻŋāĻŸāĻŽā§āĻ¯āĻžāĻĒ āĻšāĻŋāĻĒ āĻ¸ā§āĻ•ā§āĻ¯āĻžāĻ¨ āĻ¨āĻŋāĻœā§‡āĻ‡ āĻŦā§‡āĻļ āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ°āĨ¤ āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ¯āĻžāĻ‡ āĻšā§‹āĻ• 7 āĻ—ā§āĻŖ āĻĻā§āĻ°ā§āĻ¤ āĻāĻŦāĻ‚ 2.5 āĻ—ā§āĻŖ āĻ•āĻŽ āĻĒāĻĄāĻŧāĻž.

#3: āĻ‡āĻ¨ā§āĻĄā§‡āĻ•ā§āĻ¸ āĻāĻ•āĻ¤ā§āĻ°āĻŋāĻ¤ āĻ•āĻ°ā§āĻ¨ (āĻŦāĻŋāĻŸāĻŽā§āĻ¯āĻžāĻĒāĻ…āĻ°)

āĻ¯āĻ–āĻ¨ āĻ‰āĻĻāĻ¯āĻŧ āĻšāĻ¯āĻŧ

āĻ†āĻĒāĻ¨āĻžāĻ° āĻ…āĻ—ā§āĻ°āĻžāĻ§āĻŋāĻ•āĻžāĻ° āĻ¸āĻš, āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ°āĻŖā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻĨāĻŽ 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;

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[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, йОĐģŅŒŅˆĐĩ и ĐŊĐĩ ĐŊĐ°Đ´Đž

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻ†āĻŽāĻ°āĻž āĻāĻ‡ āĻ¸āĻ¤ā§āĻ¯ā§‡āĻ° āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻ¨āĻŋāĻ¯āĻŧā§‡āĻ›āĻŋ āĻ¯ā§‡ āĻĒā§āĻ°āĻĨāĻŽ āĻŦā§āĻ˛āĻ•ā§‡ 20āĻŸāĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧ āĻ°ā§‡āĻ•āĻ°ā§āĻĄ āĻ…āĻŦāĻŋāĻ˛āĻŽā§āĻŦā§‡ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ¤āĻžāĻ‡ āĻĻā§āĻŦāĻŋāĻ¤ā§€āĻ¯āĻŧāĻŸāĻŋ, āĻ†āĻ°āĻ“ "āĻŦā§āĻ¯āĻ¯āĻŧāĻŦāĻšā§āĻ˛" āĻŦāĻŋāĻŸāĻŽā§āĻ¯āĻžāĻĒ āĻšāĻŋāĻĒ āĻ¸ā§āĻ•ā§āĻ¯āĻžāĻ¨ āĻ¸āĻš, āĻāĻŽāĻ¨āĻ•āĻŋ āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻ•āĻ°āĻž āĻšāĻ¯āĻŧāĻ¨āĻŋ - āĻļā§‡āĻˇ āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ 22 āĻ—ā§āĻŖ āĻĻā§āĻ°ā§āĻ¤, 44 āĻ—ā§āĻŖ āĻ•āĻŽ āĻĒāĻĄāĻŧāĻž!

āĻāĻ‡ āĻ…āĻĒā§āĻŸāĻŋāĻŽāĻžāĻ‡āĻœā§‡āĻļāĻžāĻ¨ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ†āĻ°ā§‹ āĻŦāĻŋāĻ¸ā§āĻ¤āĻžāĻ°āĻŋāĻ¤ āĻ—āĻ˛ā§āĻĒ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ‰āĻĻāĻžāĻšāĻ°āĻŖ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡ āĻĒāĻĄāĻŧāĻž āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻĒā§‹āĻ¸ā§āĻŸāĻ—ā§āĻ°ā§‡āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ•ā§āĻˇāĻ¤āĻŋāĻ•āĻžāĻ°āĻ• āĻ¯ā§‹āĻ—āĻĻāĻžāĻ¨ āĻāĻŦāĻ‚ āĻ“āĻ†āĻ° и āĻĒā§‹āĻ¸ā§āĻŸāĻ—ā§āĻ°ā§‡āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ¨āĻžāĻŽā§‡āĻ° āĻĻā§āĻŦāĻžāĻ°āĻž āĻ…āĻ¨ā§āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ā§‡āĻ° āĻĒā§āĻ¨āĻ°āĻžāĻŦā§ƒāĻ¤ā§āĻ¤āĻŋāĻŽā§‚āĻ˛āĻ• āĻĒāĻ°āĻŋāĻŽāĻžāĻ°ā§āĻœāĻ¨āĻžāĻ° āĻ—āĻ˛ā§āĻĒ, āĻŦāĻž "āĻ…āĻĒā§āĻŸāĻŋāĻŽāĻžāĻ‡āĻœ āĻ•āĻ°āĻž āĻāĻŦāĻ‚ āĻ¸āĻžāĻŽāĻ¨ā§‡āĻ° āĻĻāĻŋāĻ•ā§‡".

āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āĻ¨ āĻ•ā§€āĻ—ā§āĻ˛āĻŋāĻ° āĻ‰āĻĒāĻ° āĻ­āĻŋāĻ¤ā§āĻ¤āĻŋ āĻ•āĻ°ā§‡ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ¨ā§‡āĻ° āĻ†āĻĻā§‡āĻļ āĻĻā§‡āĻ“āĻ¯āĻŧāĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ (āĻāĻŦāĻ‚ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° const/NULL āĻœā§‹āĻĄāĻŧāĻž āĻ¨āĻ¯āĻŧ) āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡ āĻ†āĻ˛ā§‹āĻšāĻ¨āĻž āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ SQL HowTo: āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€āĻ¤ā§‡ āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ āĻ•āĻŋāĻ›ā§āĻ•ā§āĻˇāĻŖ āĻ˛ā§āĻĒ āĻ˛āĻŋāĻ–ā§āĻ¨ āĻŦāĻž "āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ• āĻ¤āĻŋāĻ¨-āĻĒāĻĻāĻ•ā§āĻˇā§‡āĻĒ".

#4: āĻ†āĻŽāĻ°āĻž āĻ…āĻ¨ā§‡āĻ• āĻ…āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧ āĻœāĻŋāĻ¨āĻŋāĻ¸ āĻĒāĻĄāĻŧāĻŋ

āĻ¯āĻ–āĻ¨ āĻ‰āĻĻāĻ¯āĻŧ āĻšāĻ¯āĻŧ

āĻāĻ•āĻŸāĻŋ āĻ¨āĻŋāĻ¯āĻŧāĻŽ āĻšāĻŋāĻ¸āĻžāĻŦā§‡, āĻ¯āĻ–āĻ¨ āĻ†āĻĒāĻ¨āĻŋ āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻŦāĻŋāĻĻā§āĻ¯āĻŽāĻžāĻ¨ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡ "āĻ…āĻ¨ā§āĻ¯ āĻĢāĻŋāĻ˛ā§āĻŸāĻžāĻ° āĻ¸āĻ‚āĻ¯ā§āĻ•ā§āĻ¤ āĻ•āĻ°āĻ¤ā§‡" āĻšāĻžāĻ¨ āĻ¤āĻ–āĻ¨ āĻāĻŸāĻŋ āĻĻā§‡āĻ–āĻž āĻĻā§‡āĻ¯āĻŧāĨ¤

"āĻāĻŦāĻ‚ āĻ†āĻĒāĻ¨āĻžāĻ° āĻāĻ•āĻ‡ āĻāĻ•āĻŸāĻŋ āĻ¨ā§‡āĻ‡, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻŽā§āĻ•ā§āĻ¤āĻžāĻ° āĻŦā§‹āĻ¤āĻžāĻŽ āĻ¸āĻš? " āĻĢāĻŋāĻ˛ā§āĻŽ "āĻĄāĻžāĻ¯āĻŧāĻŽāĻ¨ā§āĻĄ āĻ†āĻ°ā§āĻŽ"

āĻ‰āĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§‚āĻĒ, āĻ‰āĻĒāĻ°ā§‡āĻ° āĻŸāĻžāĻ¸ā§āĻ•āĻŸāĻŋ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻ•āĻ°ā§‡, āĻ¤āĻžāĻĻā§‡āĻ° āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ āĻ¨āĻŋāĻ°ā§āĻŦāĻŋāĻļā§‡āĻˇā§‡, āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ°āĻŖā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻĨāĻŽ 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;

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻ¸āĻ‚āĻļā§‹āĻ§āĻ¨ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡:

CREATE INDEX ON tbl(pk)
  WHERE critical; -- дОйавиĐģи "ŅŅ‚Đ°Ņ‚иŅ‡ĐŊĐžĐĩ" ŅƒŅĐģОвиĐĩ Ņ„иĐģŅŒŅ‚Ņ€Đ°Ņ†Đ¸Đ¸

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[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

āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ

āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¯āĻŧāĻžāĻ˛āĻŋ āĻ¨āĻŋāĻ¯āĻŧāĻŽāĻŋāĻ¤ āĻ†āĻ‰āĻŸ āĻŦāĻšāĻ¨ āĻ­ā§āĻ¯āĻžāĻ•ā§āĻ¯āĻŧāĻžāĻŽ [āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ] āĻŦāĻž āĻĒāĻ°ā§āĻ¯āĻžāĻĒā§āĻ¤ āĻ˜āĻ¨ āĻ˜āĻ¨ āĻĒā§āĻ°āĻļāĻŋāĻ•ā§āĻˇāĻŖ āĻ…āĻ°ā§āĻœāĻ¨ āĻ•āĻ°ā§āĻ¨ āĻ…āĻŸā§‹āĻ­ā§āĻ¯āĻžāĻ•ā§āĻ¯āĻŧāĻžāĻŽ āĻāĻ° āĻĒāĻ°āĻžāĻŽāĻŋāĻ¤āĻŋāĻ—ā§āĻ˛āĻŋāĻ•ā§‡ āĻĢāĻžāĻ‡āĻ¨-āĻŸāĻŋāĻ‰āĻ¨āĻŋāĻ‚ āĻ•āĻ°ā§‡, āĻ¸āĻš āĻāĻ•āĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻŸā§‡āĻŦāĻŋāĻ˛ā§‡āĻ° āĻœāĻ¨ā§āĻ¯.

āĻŦā§‡āĻļāĻŋāĻ°āĻ­āĻžāĻ— āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻāĻ‡ āĻ§āĻ°āĻ¨ā§‡āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ—ā§āĻ˛āĻŋ āĻ–āĻžāĻ°āĻžāĻĒ āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻ•āĻŽā§āĻĒā§‹āĻœāĻŋāĻļāĻ¨ā§‡āĻ° āĻ•āĻžāĻ°āĻŖā§‡ āĻ¸ā§ƒāĻˇā§āĻŸ āĻšāĻ¯āĻŧ āĻ¯āĻ–āĻ¨ āĻŦāĻŋāĻœāĻ¨ā§‡āĻ¸ āĻ˛āĻœāĻŋāĻ• āĻĨā§‡āĻ•ā§‡ āĻ•āĻ˛ āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¯ā§‡āĻŽāĻ¨ āĻ†āĻ˛ā§‹āĻšāĻ¨āĻž āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ āĻĒā§‹āĻ¸ā§āĻŸāĻ—ā§āĻ°ā§‡āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: "āĻŽā§ƒāĻ¤āĻĻā§‡āĻ°" āĻ¸ā§ˆāĻ¨ā§āĻ¯āĻĻā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ˛āĻĄāĻŧāĻžāĻ‡ āĻ•āĻ°āĻž.

āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻŦā§āĻāĻ¤ā§‡ āĻšāĻŦā§‡ āĻ¯ā§‡ āĻāĻŽāĻ¨āĻ•āĻŋ āĻ­ā§āĻ¯āĻžāĻ•ā§āĻ¯āĻŧāĻžāĻŽ āĻĢā§āĻ˛ āĻ¸āĻŦāĻ¸āĻŽāĻ¯āĻŧ āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻ¨āĻžāĨ¤ āĻāĻ‡ āĻœāĻžāĻ¤ā§€āĻ¯āĻŧ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡, āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ āĻĨā§‡āĻ•ā§‡ āĻ…ā§āĻ¯āĻžāĻ˛āĻ—āĻ°āĻŋāĻĻāĻŽā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ¨āĻŋāĻœā§‡āĻ•ā§‡ āĻĒāĻ°āĻŋāĻšāĻŋāĻ¤ āĻ•āĻ°āĻž āĻŽā§‚āĻ˛ā§āĻ¯āĻŦāĻžāĻ¨ āĻĄāĻŋāĻŦāĻŋāĻ: āĻ­ā§āĻ¯āĻžāĻ•ā§āĻ¯āĻŧāĻžāĻŽ āĻŦā§āĻ¯āĻ°ā§āĻĨ āĻšāĻ˛ā§‡, āĻ†āĻŽāĻ°āĻž āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¯āĻŧāĻžāĻ˛āĻŋ āĻŸā§‡āĻŦāĻŋāĻ˛āĻŸāĻŋ āĻĒāĻ°āĻŋāĻˇā§āĻ•āĻžāĻ° āĻ•āĻ°āĻŋ.

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

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ āĻŋāĻ• āĻ†āĻ›ā§‡ āĻŦāĻ˛ā§‡ āĻŽāĻ¨ā§‡ āĻšāĻšā§āĻ›ā§‡, āĻāĻŽāĻ¨āĻ•āĻŋ āĻ¸ā§‚āĻšāĻ• āĻ…āĻ¨ā§āĻ¯āĻžāĻ¯āĻŧā§€, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻŸāĻŋ āĻāĻ•āĻ°āĻ•āĻŽ āĻ¸āĻ¨ā§āĻĻā§‡āĻšāĻœāĻ¨āĻ• - āĻĒāĻĄāĻŧāĻž 20āĻŸāĻŋ āĻ°ā§‡āĻ•āĻ°ā§āĻĄā§‡āĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋāĻ° āĻœāĻ¨ā§āĻ¯, āĻ†āĻŽāĻžāĻĻā§‡āĻ° 4 āĻĒā§ƒāĻˇā§āĻ āĻžāĻ° āĻĄā§‡āĻŸāĻž āĻŦāĻŋāĻ¯āĻŧā§‹āĻ— āĻ•āĻ°āĻ¤ā§‡ āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛, āĻ°ā§‡āĻ•āĻ°ā§āĻĄ āĻĒā§āĻ°āĻ¤āĻŋ 32KB - āĻāĻŸāĻŋ āĻ•āĻŋ āĻ¸āĻžāĻšāĻ¸ā§€ āĻ¨āĻ¯āĻŧ? āĻāĻŦāĻ‚ āĻ¸ā§‚āĻšāĻ• āĻ¨āĻžāĻŽ tbl_fk_org_fk_cli_idx āĻšāĻŋāĻ¨ā§āĻ¤āĻž-āĻ‰āĻĻā§āĻĻā§€āĻĒāĻ•

āĻ¸āĻ‚āĻļā§‹āĻ§āĻ¨ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡:

CREATE INDEX ON tbl(fk_cli);

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻšāĻ āĻžā§Ž- 10 āĻ—ā§āĻŖ āĻĻā§āĻ°ā§āĻ¤, āĻāĻŦāĻ‚ 4 āĻ—ā§āĻŖ āĻ•āĻŽ āĻĒāĻĄāĻŧāĻ¤ā§‡!

āĻ¸ā§‚āĻšāĻ•āĻ—ā§āĻ˛āĻŋāĻ° āĻ…āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§‡āĻ° āĻĒāĻ°āĻŋāĻ¸ā§āĻĨāĻŋāĻ¤āĻŋāĻ—ā§āĻ˛āĻŋāĻ° āĻ…āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻ‰āĻĻāĻžāĻšāĻ°āĻŖ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§‡ āĻĻā§‡āĻ–āĻž āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ DBA: āĻ…āĻ•ā§‡āĻœā§‹ āĻ¸ā§‚āĻšā§€ āĻ–ā§‹āĻāĻœāĻž.

#7: CTE × CTE

āĻ¯āĻ–āĻ¨ āĻ‰āĻĻāĻ¯āĻŧ āĻšāĻ¯āĻŧ

āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ā§‡ āĻ¸ā§āĻ•ā§‹āĻ° "āĻĢā§āĻ¯āĻžāĻŸ" CTE āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āĻ¨ āĻŸā§‡āĻŦāĻŋāĻ˛ āĻĨā§‡āĻ•ā§‡, āĻāĻŦāĻ‚ āĻ¤āĻžāĻ°āĻĒāĻ° āĻ¤āĻžāĻĻā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻāĻŸāĻŋ āĻ•āĻ°āĻžāĻ° āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨āĻŋāĻ¯āĻŧā§‡āĻ›ā§‡ JOIN.

āĻ•ā§‡āĻ¸āĻŸāĻŋ v12 āĻāĻ° āĻ¨ā§€āĻšā§‡āĻ° āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖāĻ—ā§āĻ˛āĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻŦāĻž āĻāĻ° āĻ¸āĻžāĻĨā§‡ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§āĻ—ā§āĻ˛āĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻžāĻ¸āĻ™ā§āĻ—āĻŋāĻ•ā§ˇ WITH MATERIALIZED.

āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻ¸āĻ¨āĻžāĻ•ā§āĻ¤ āĻ•āĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ

-> CTE Scan
   && loops > 10
   && loops × (rows + RRbF) > 10000
      -- ŅĐģиŅˆĐēĐžĐŧ йОĐģŅŒŅˆĐžĐĩ Đ´ĐĩĐēĐ°Ņ€Ņ‚ОвО ĐŋŅ€ĐžĐ¸ĐˇĐ˛ĐĩĐ´ĐĩĐŊиĐĩ CTE

āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ

āĻ…āĻ¨ā§āĻ°ā§‹āĻ§āĻŸāĻŋ āĻ¸āĻžāĻŦāĻ§āĻžāĻ¨āĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§‡ āĻŦāĻŋāĻļā§āĻ˛ā§‡āĻˇāĻŖ āĻ•āĻ°ā§āĻ¨ - āĻāĻŦāĻ‚ āĻāĻ–āĻžāĻ¨ā§‡ āĻ•āĻŋ CTEs āĻ†āĻĻā§Œ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨?? āĻ¯āĻĻāĻŋ āĻšā§āĻ¯āĻžāĻ, āĻ¤āĻžāĻšāĻ˛ā§‡ hstore/json āĻ "āĻ…āĻ­āĻŋāĻ§āĻžāĻ¨" āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻ— āĻ•āĻ°ā§āĻ¨ āĻŦāĻ°ā§āĻŖāĻŋāĻ¤ āĻŽāĻĄā§‡āĻ˛ āĻ…āĻ¨ā§āĻ¯āĻžāĻ¯āĻŧā§€ āĻĒā§‹āĻ¸ā§āĻŸāĻ—ā§āĻ°ā§‡āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ†āĻ¸ā§āĻ¨ āĻāĻ•āĻŸāĻŋ āĻ…āĻ­āĻŋāĻ§āĻžāĻ¨ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ­āĻžāĻ°ā§€ āĻ¯ā§‹āĻ—āĻĻāĻžāĻ¨ āĻ•āĻ°āĻŋ.

#8: āĻĄāĻŋāĻ¸ā§āĻ•ā§‡ āĻ…āĻĻāĻ˛āĻŦāĻĻāĻ˛ (āĻŸā§‡āĻŽā§āĻĒāĻ˛āĻŋ āĻ˛ā§‡āĻ–āĻž)

āĻ¯āĻ–āĻ¨ āĻ‰āĻĻāĻ¯āĻŧ āĻšāĻ¯āĻŧ

āĻŦāĻŋāĻĒā§āĻ˛ āĻ¸āĻ‚āĻ–ā§āĻ¯āĻ• āĻ°ā§‡āĻ•āĻ°ā§āĻĄā§‡āĻ° āĻāĻ•āĻ•āĻžāĻ˛ā§€āĻ¨ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻ•āĻ°āĻŖ (āĻŦāĻžāĻ›āĻžāĻ‡ āĻŦāĻž āĻ…āĻ¨āĻ¨ā§āĻ¯āĻ•āĻ°āĻŖ) āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻŦāĻ°āĻžāĻĻā§āĻĻ āĻ•āĻ°āĻž āĻŽā§‡āĻŽāĻ°āĻŋāĻ° āĻ¸āĻžāĻĨā§‡ āĻ–āĻžāĻĒ āĻ–āĻžāĻ¯āĻŧ āĻ¨āĻžāĨ¤

āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻ¸āĻ¨āĻžāĻ•ā§āĻ¤ āĻ•āĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ

-> *
   && temp written > 0

āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ

āĻ…āĻĒāĻžāĻ°ā§‡āĻļāĻ¨ āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻŽā§‡āĻŽāĻ°āĻŋ āĻĒāĻ°āĻŋāĻŽāĻžāĻŖ āĻŦā§āĻ¯āĻžāĻĒāĻ•āĻ­āĻžāĻŦā§‡ āĻĒāĻ°āĻžāĻŽāĻŋāĻ¤āĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻŽāĻžāĻ¨ āĻ…āĻ¤āĻŋāĻ•ā§āĻ°āĻŽ āĻ¨āĻž āĻšāĻ˛ā§‡ āĻ•āĻžāĻœ_āĻŽā§‡āĻŽ, āĻāĻŸāĻž āĻ¸āĻ‚āĻļā§‹āĻ§āĻ¨ āĻŽā§‚āĻ˛ā§āĻ¯. āĻ†āĻĒāĻ¨āĻŋ āĻ…āĻŦāĻŋāĻ˛āĻŽā§āĻŦā§‡ āĻĒā§āĻ°āĻ¤ā§āĻ¯ā§‡āĻ•ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ•āĻ¨āĻĢāĻŋāĻ—āĻžāĻ°ā§‡āĻļāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨, āĻ…āĻĨāĻŦāĻž āĻ†āĻĒāĻ¨āĻŋ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨ SET [LOCAL] āĻāĻ•āĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§/āĻ˛ā§‡āĻ¨āĻĻā§‡āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯āĨ¤

āĻ‰āĻĻāĻžāĻšāĻ°āĻŖ:

SHOW work_mem;
-- "16MB"

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

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻ¸āĻ‚āĻļā§‹āĻ§āĻ¨ āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡:

SET work_mem = '128MB'; -- ĐŋĐĩŅ€ĐĩĐ´ вŅ‹ĐŋĐžĐģĐŊĐĩĐŊиĐĩĐŧ СаĐŋŅ€ĐžŅĐ°

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻ¸ā§āĻ¸ā§āĻĒāĻˇā§āĻŸ āĻ•āĻžāĻ°āĻŖā§‡, āĻ¯āĻĻāĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻŽā§‡āĻŽāĻ°āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻĄāĻŋāĻ¸ā§āĻ• āĻ¨āĻ¯āĻŧ, āĻ¤āĻžāĻšāĻ˛ā§‡ āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€āĻŸāĻŋ āĻ…āĻ¨ā§‡āĻ• āĻĻā§āĻ°ā§āĻ¤ āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻšāĻŦā§‡āĨ¤ āĻāĻ•āĻ‡ āĻ¸āĻŽāĻ¯āĻŧā§‡, HDD āĻĨā§‡āĻ•ā§‡ āĻ˛ā§‹āĻĄā§‡āĻ° āĻ…āĻ‚āĻļāĻ“ āĻ¸āĻ°āĻžāĻ¨ā§‹ āĻšāĻ¯āĻŧāĨ¤

āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻŦā§āĻāĻ¤ā§‡ āĻšāĻŦā§‡ āĻ¯ā§‡ āĻ†āĻĒāĻ¨āĻŋ āĻ¸āĻ°ā§āĻŦāĻĻāĻž āĻĒā§āĻ°āĻšā§āĻ° āĻāĻŦāĻ‚ āĻĒā§āĻ°āĻšā§āĻ° āĻŽā§‡āĻŽāĻ°āĻŋ āĻŦāĻ°āĻžāĻĻā§āĻĻ āĻ•āĻ°āĻ¤ā§‡ āĻ¸āĻ•ā§āĻˇāĻŽ āĻšāĻŦā§‡āĻ¨ āĻ¨āĻž - āĻ¸ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ¸āĻŦāĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¯āĻĨā§‡āĻˇā§āĻŸ āĻšāĻŦā§‡ āĻ¨āĻžāĨ¤

#9: āĻ…āĻĒā§āĻ°āĻžāĻ¸āĻ™ā§āĻ—āĻŋāĻ• āĻĒāĻ°āĻŋāĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĻ¨

āĻ¯āĻ–āĻ¨ āĻ‰āĻĻāĻ¯āĻŧ āĻšāĻ¯āĻŧ

āĻ¤āĻžāĻ°āĻž āĻāĻ•āĻŦāĻžāĻ°ā§‡ āĻĄāĻžāĻŸāĻžāĻŦā§‡āĻ¸ā§‡ āĻ…āĻ¨ā§‡āĻ• āĻ•āĻŋāĻ›ā§ āĻĸā§‡āĻ˛ā§‡ āĻĻāĻŋāĻ¯āĻŧā§‡āĻ›ā§‡, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻŸāĻŋ āĻĻā§‚āĻ°ā§‡ āĻ¸āĻ°āĻŋāĻ¯āĻŧā§‡ āĻĻā§‡āĻ“āĻ¯āĻŧāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ›āĻŋāĻ˛ āĻ¨āĻž ANALYZE.

āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻ¸āĻ¨āĻžāĻ•ā§āĻ¤ āĻ•āĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ

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

āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ

āĻāĻŸāĻž āĻŦāĻšāĻ¨ āĻ•āĻ°ā§‡ āĻ¨āĻžāĻ“ ANALYZE.

āĻāĻ‡ āĻĒāĻ°āĻŋāĻ¸ā§āĻĨāĻŋāĻ¤āĻŋ āĻ†āĻ°āĻ“ āĻŦāĻŋāĻļāĻĻā§‡ āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ PostgreSQL Antipatterns: āĻĒāĻ°āĻŋāĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĻ¨ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§.

#10: "āĻ•āĻŋāĻ›ā§ āĻ­ā§āĻ˛ āĻšāĻ¯āĻŧā§‡āĻ›ā§‡"

āĻ¯āĻ–āĻ¨ āĻ‰āĻĻāĻ¯āĻŧ āĻšāĻ¯āĻŧ

āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻ¯ā§‹āĻ—ā§€ āĻ…āĻ¨ā§āĻ°ā§‹āĻ§ āĻĻā§āĻŦāĻžāĻ°āĻž āĻ†āĻ°ā§‹āĻĒāĻŋāĻ¤ āĻāĻ•āĻŸāĻŋ āĻ˛āĻ•ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ…āĻĒā§‡āĻ•ā§āĻˇāĻž āĻ›āĻŋāĻ˛, āĻ…āĻĨāĻŦāĻž āĻ…āĻĒāĻ°ā§āĻ¯āĻžāĻĒā§āĻ¤ CPU/āĻšāĻžāĻ‡āĻĒāĻžāĻ°āĻ­āĻžāĻ‡āĻœāĻžāĻ° āĻšāĻžāĻ°ā§āĻĄāĻ“āĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻ¸āĻ‚āĻ¸ā§āĻĨāĻžāĻ¨ āĻ›āĻŋāĻ˛āĨ¤

āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻ¸āĻ¨āĻžāĻ•ā§āĻ¤ āĻ•āĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ

-> *
   && (shared hit / 8K) + (shared read / 1K) < time / 1000
      -- RAM hit = 64MB/s, HDD read = 8MB/s
   && time > 100ms -- Ņ‡Đ¸Ņ‚Đ°Đģи ĐŧĐ°ĐģĐž, ĐŊĐž ŅĐģиŅˆĐēĐžĐŧ Đ´ĐžĐģĐŗĐž

āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ

āĻŦāĻžāĻšā§āĻ¯āĻŋāĻ• āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§āĻ¨ āĻĒāĻ°ā§āĻ¯āĻŦā§‡āĻ•ā§āĻˇāĻŖ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻŦā§āĻ˛āĻ•āĻŋāĻ‚ āĻŦāĻž āĻ…āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ• āĻ¸āĻŽā§āĻĒāĻĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ°āĨ¤ āĻ†āĻŽāĻ°āĻž āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻļāĻ¤ āĻļāĻ¤ āĻ¸āĻžāĻ°ā§āĻ­āĻžāĻ°ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ‡ āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻŸāĻŋ āĻ¸āĻ‚āĻ—āĻ āĻŋāĻ¤ āĻ•āĻ°āĻžāĻ° āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ•āĻĨāĻž āĻŦāĻ˛ā§‡āĻ›āĻŋ āĻāĻ–āĻžāĻ¨ā§‡ и āĻāĻ–āĻžāĻ¨ā§‡.

āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ
āĻ…āĻ¸ā§āĻ¸ā§āĻĨ āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ°ā§‡āĻ¸āĻŋāĻĒāĻŋ

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨