{"id":478614,"date":"2026-05-05T09:20:18","date_gmt":"2026-05-05T09:20:18","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=478614"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=478614","title":{"rendered":"\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0432 PostgreSQL (\u043d\u0430 \u0430\u043f\u0440\u0435\u043b\u044c 2026 \u0433\u043e\u0434\u0430)"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e.<\/p>\n<p>\u0418\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0440\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0435 \u0432 PostgreSQL. \u0410\u0434\u043c\u0438\u043d\u044b \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043f\u043e\u0434\u0443\u043c\u0430\u044e\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u044f \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e \u0432\u0441\u044f\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432, \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0411\u0443\u0434\u0443. \u0422\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437 \u043f\u043e\u0439\u0434\u0435\u0442 \u043d\u0435 \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0430 \u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0431\u044c\u0435\u0442\u0435 \u0432 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a\u0435 \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u201c\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 postgresql\u201d, \u0442\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c, \u043d\u0430 \u0447\u0442\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c, &#8212; \u044d\u0442\u043e <code>CREATE AGGREGATE<\/code> \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0438\/\u0438\u043b\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u201c\u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0433\u043e\u201d <code>GROUP BY GROUPING SETS<\/code>. \u041d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0438 \u0441\u043b\u043e\u0432\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430.<\/p>\n<p>\u041c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u0434\u043e\u043c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 (\u0437\u0430\u0447\u0435\u043c &#8212; \u0432 \u043a\u043e\u043d\u0446\u0435). \u041a\u043e\u0433\u0434\u0430 \u0434\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u0437\u0430\u0434\u0430\u0447\u0443, \u0441\u0430\u043c\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u044f \u0432\u044b\u0434\u0435\u043b\u0438\u043b \u043b\u043e\u0433\u0438\u043a\u0443 \u0441\u0431\u0440\u043e\u0441\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a. \u041d\u043e \u043f\u043e\u0442\u043e\u043c \u0432\u044b\u0448\u043b\u043e, \u0447\u0442\u043e \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u0441\u0430\u043c\u043e\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0435 &#8212; \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043c\u043e\u0434\u0443\u043b\u044c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c.<\/p>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u043c\u043e\u0435\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u043d\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 PG BootCamp (<a href=\"https:\/\/www.youtube.com\/watch?v=bt1FjjEw6Ps\">YouTube<\/a>\/<a href=\"https:\/\/rutube.ru\/video\/8ed09434c98becdeced43b47074b28f4\/\">RuTube<\/a>). \u0418\u0437-\u0437\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043c\u043d\u043e\u0433\u043e\u0435 \u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u201c\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0439\u201d \u0432\u0435\u0440\u0441\u0438\u0435\u0439. \u0412 \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u043e \u044f\u0434\u0440\u043e \u0438 \u0432\u044b\u043d\u0435\u0441 \u0437\u0430 \u0441\u043a\u043e\u0431\u043a\u0438 \u0432\u0441\u0435, \u0447\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043d\u0435\u0432\u0430\u0436\u043d\u044b\u043c. \u0417\u0434\u0435\u0441\u044c \u044d\u0442\u043e \u0432\u0441\u0435 \u0435\u0441\u0442\u044c.<\/p>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435:<\/p>\n<ol>\n<li>\n<p><a href=\"#%D0%B0%D0%B3%D1%80%D0%B5%D0%B3%D0%B0%D1%82%D0%BD%D1%8B%D0%B5-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8\">\u0410\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#%D0%BF%D0%BB%D0%BE%D1%81%D0%BA%D0%B0%D1%8F-%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0\">\u041f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0-%D0%BF%D0%BE-%D0%B0%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D0%B0%D0%BC\">\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c<\/a> <\/p>\n<ol>\n<li>\n<p><a href=\"#%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0\">\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">\u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81%D0%B1%D1%80%D0%BE%D1%81-%D0%BD%D0%B0-%D0%B4%D0%B8%D1%81%D0%BA\">\u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0441\u0431\u0440\u043e\u0441 \u043d\u0430 \u0434\u0438\u0441\u043a<\/a><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p><a href=\"#%D1%81%D0%BB%D0%BE%D0%B6%D0%BD%D1%8B%D0%B5-%D0%B0%D0%BD%D0%B0%D0%BB%D0%B8%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B5-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8-grouping-set-cube-rollup\">GROUPING SETS<\/a> <\/p>\n<ol>\n<li>\n<p><a href=\"#%D1%85%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5gs\">\u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0gs\">\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#mixedaggregate\">\u0421\u043c\u0435\u0448\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f<\/a><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p><a href=\"#%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D1%88%D0%B5%D0%B5%D1%81%D1%8F-%D0%B7%D0%B0-%D0%BA%D0%B0%D0%B4%D1%80%D0%BE%D0%BC\">\u041e\u0441\u0442\u0430\u0432\u0448\u0435\u0435\u0441\u044f \u0437\u0430 \u043a\u0430\u0434\u0440\u043e\u043c<\/a> <\/p>\n<ol>\n<li>\n<p><a href=\"#%D1%87%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%BD%D0%B0%D1%8F-%D0%B0%D0%B3%D1%80%D0%B5%D0%B3%D0%B0%D1%86%D0%B8%D1%8F\">\u0427\u0430\u0441\u0442\u0438\u0447\u043d\u0430\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044f<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#ordered-setdistinct-%D0%B0%D0%B3%D1%80%D0%B5%D0%B3%D0%B0%D1%82%D1%8B\">ORDERED SET AGGREGATE<\/a><\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p><a href=\"#index-aggregate\">Index Aggregate<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#%D0%B7%D0%B0%D0%BA%D0%BB%D1%8E%D1%87%D0%B5%D0%BD%D0%B8%D0%B5\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<\/ol>\n<h3>\u0410\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h3>\n<p>\u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f. \u042d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0449\u0430\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u0442\u044c 2 \u044f\u0440\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430: <code>max<\/code> &#8212; \u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0438 <code>avg<\/code> &#8212; \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435.<\/p>\n<pre><code class=\"sql\">-- \u0421\u0430\u043c\u044b\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0438 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439SELECT max(age) FROM users;-- \u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044fSELECT userid, avg(transferred) FROM user_transactions GROUP BY userid;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c <code>max<\/code>, \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0447\u0438\u0441\u043b\u043e &#8212; \u0441\u0430\u043c\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, &#8212; \u0438 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435\u0435. \u0410 \u0432\u043e\u0442 \u0434\u043b\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u0447\u0435\u0442\u0430 <code>avg<\/code> \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0443\u0436\u0435 \u0434\u0432\u0430 \u0447\u0438\u0441\u043b\u0430 &#8212; \u0441\u0443\u043c\u043c\u0443 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u0443\u043c\u043c\u0443 \u043d\u0430 \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e, \u0430 \u043f\u0435\u0440\u0435\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0434\u0435\u043b\u0438\u043c \u0441\u0443\u043c\u043c\u0443 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e.<\/p>\n<p>\u0412\u044b\u0445\u043e\u0434\u0438\u0442, \u0447\u0442\u043e \u0443 \u0440\u0430\u0437\u043d\u044b\u0445 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u0440\u0430\u0437\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0437\u043e\u043e\u043f\u0430\u0440\u043a, \u0431\u044b\u043b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u043c\u0438.<\/p>\n<blockquote>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435, \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u201c\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430\u201d \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 &#8212; \u044d\u0442\u043e \u043c\u043e\u0435 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u0443\u043c\u0435\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u044e \u044d\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443.<\/p>\n<\/blockquote>\n<p>\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"python\"># \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044fstate = init()# \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430for tuple in input:   state = transit(state, tuple)# \u041f\u043e\u0434\u0441\u0447\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430result = finalize(state)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>CREATE AGGREGATE<\/code> \u044d\u0442\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u043c\u044b \u0438 \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c:<\/p>\n<pre><code class=\"sql\">CREATE AGGREGATE some_agg(a int, b int) (   -- \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435   initcond  = '(0,0)'   -- \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430   sfunc     = average_transition,   -- \u0424\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440   finalfunc = average_final,   -- ...)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0441\u0435 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 <code>pg_aggregate<\/code>. \u0415\u0441\u0442\u044c \u0443\u0436\u0435 \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432, \u043d\u043e \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435:<\/p>\n<pre><code class=\"sql\">select aggfnoid, agginitval, aggtransfn, aggfinalfn from pg_aggregate;         aggfnoid       |    agginitval   |    aggtransfn    |      aggfinalfn        ------------------------+-----------------+------------------+----------------------- pg_catalog.stddev      | {0,0,0}         | float4_accum     | float8_stddev_samp pg_catalog.avg         | {0,0,0}         | float4_accum     | float8_avg pg_catalog.avg         | {0,0}           | int4_avg_accum   | int8_avg pg_catalog.max         |                 | int4larger       | - pg_catalog.max         |                 | float4larger     | -  ...<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b (\u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u043b\u044f <code>int4<\/code>):<\/p>\n<ul>\n<li>\n<p><code>avg<\/code> &#8212; \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 &#8212; \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0434\u0432\u0443\u0445 \u043d\u0443\u043b\u0435\u0439 (\u0441\u0443\u043c\u043c\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e), \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 <code>int4_avg_accum<\/code> &#8212; \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0443\u043c\u043c\u0443 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e, \u0430 <code>int8_avg<\/code> \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 &#8212; \u0434\u0435\u043b\u0438\u0442 \u0438\u0445. <\/p>\n<blockquote>\n<p>\u0414\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f <code>avg<\/code> &#8212; \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0447\u0438\u0441\u0435\u043b, \u0430 \u043d\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441 \u0434\u0432\u0443\u043c\u044f \u043f\u043e\u043b\u044f\u043c\u0438. \u041f\u043e\u0434\u043e\u0431\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u0442\u0438\u043f\u044b, \u0442.\u043a. \u0442\u0438\u043f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0430 \u0435\u0441\u043b\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f, \u0442\u043e \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u0431\u0443\u0445\u043d\u0435\u0442.<\/p>\n<\/blockquote>\n<\/li>\n<li>\n<p><code>max<\/code> &#8212; \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 <code>int4larger<\/code>, \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043d\u0435\u0442 (<code>NULL<\/code>) \u0438 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0442\u043e\u0436\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>NULL<\/code> &#8212; \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u043e\u0435 \u043d\u0435 <code>NULL<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f. \u0410 \u0435\u0441\u043b\u0438 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u043d\u0435\u0442, \u0442\u043e \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0435\u0441\u0442\u044c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 <code>max<\/code> \u0432\u0441\u0435 \u044d\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442: \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e, \u0430 \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u0430\u043c\u043e \u0447\u0438\u0441\u043b\u043e \u0438 \u0435\u0441\u0442\u044c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0442\u043e \u0438 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f <code>avg<\/code> \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043c\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"python\">state = {0, 0}for number in input:   state.count++   state.sum += numberresult = state.sum \/ state.count<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0434\u043b\u044f <code>max<\/code> \u0442\u0430\u043a:<\/p>\n<pre><code class=\"python\">state = NULLfor number in input:   if state == NULL or state &lt; number:      state = numberresult = state<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a, \u0430 \u043f\u0440\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0435. \u0421\u0430\u043c\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 &#8212; \u043f\u043b\u043e\u0441\u043a\u0430\u044f.<\/p>\n<h3>\u041f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430<\/h3>\n<pre><code class=\"sql\">SELECT avg(a) FROM tbl;       QUERY PLAN----------------------- Aggregate   -&gt;  Seq Scan on tbl(2 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0413\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 &#8212; \u044d\u0442\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044f \u043f\u043e \u0432\u0441\u0435\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c.<\/p>\n<blockquote>\n<p>\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u044e \u201c\u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 &#8212; \u044d\u0442\u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0431\u0435\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432\u201d, \u0442.\u043a. \u0442\u0430\u0432\u0442\u043e\u043b\u043e\u0433\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f<\/p>\n<\/blockquote>\n<details class=\"spoiler\">\n<summary>()<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u0442 <code>GROUP BY<\/code>, \u043d\u043e \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0434\u0430 \u043b\u0438\u0448\u044c \u043e\u0442\u0447\u0430\u0441\u0442\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0435\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 <code>()<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u043b\u043e\u0441\u043a\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"sql\">SELECT avg(a) FROM tbl GROUP BY ();<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u043f\u043b\u0430\u043d \u0431\u0443\u0434\u0435\u0442 \u0442\u0435\u043c \u0436\u0435.<\/p>\n<p>\u0412 \u0441\u0430\u043c\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 SQL (ISO\/IEC 9075, Part 2, 7.13) \u043a \u043d\u0435\u043c\u0443 \u0441\u0441\u044b\u043b\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a <code>&lt;empty grouping set&gt;<\/code>.<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0431 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043a\u043e\u0434\u0443.<\/p>\n<blockquote>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_STABLE\/src\/backend\/executor\/nodeAgg.c\"><code>src\/backend\/executor\/nodeAgg.c<\/code><\/a> \u0438, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043e\u0433\u043e\u0432\u043e\u0440\u0435\u043d\u043e \u0438\u043d\u043e\u0435, \u0432\u0435\u0441\u044c \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0442\u0430\u043c. \u0414\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438, \u0432\u0435\u0441\u044c \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u044f \u0431\u0443\u0434\u0443 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0435\u043c.<\/p>\n<\/blockquote>\n<p>PostgreSQL \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 &#8212; \u0437\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u043f\u043b\u0430\u043d\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u041e\u043d \u0447\u0438\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438\u0437 \u043f\u043e\u0434\u0443\u0437\u043b\u0430, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u043e\u0440\u0442\u0435\u0436\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u043c\u0443 (\u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u0443\u0437\u043b\u0443).<\/p>\n<details class=\"spoiler\">\n<summary>ExecAgg<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2244 *\/static TupleTableSlot *ExecAgg(PlanState *pstate){    AggState   *node = castNode(AggState, pstate);    TupleTableSlot *result = NULL;    if (!node-&gt;agg_done)    {        \/* Dispatch based on strategy *\/        switch (node-&gt;aggstrategy)        {            case AGG_HASHED:                \/* ... *\/            case AGG_MIXED:                \/* ... *\/            case AGG_PLAIN:                \/* ... *\/            case AGG_SORTED:               return agg_retrieve_direct(node);        }    }    return NULL;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0443\u0437\u043b\u0430 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>ExecAgg<\/code>, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 &#8212; \u043f\u0440\u043e\u0441\u0442\u043e\u0439 <code>switch<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u043d\u0443\u0436\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e. \u0414\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439, \u044d\u0442\u043e \u043d\u0435 \u0441\u0435\u043a\u0440\u0435\u0442. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u043f\u043b\u043e\u0441\u043a\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443, \u0438 \u0437\u0430 \u043d\u0435\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 <code>AGG_PLAIN<\/code>, \u0441\u0430\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a &#8212; <code>agg_retrieve_direct<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>agg_retrieve_direct<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2280 *\/static TupleTableSlot *agg_retrieve_direct(AggState *aggstate){   Agg           *node = aggstate-&gt;phase-&gt;aggnode;   AggStatePerAgg peragg;   AggStatePerGroup *pergroups;   \/* \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 *\/   outerslot = fetch_input_tuple(aggstate);   \/* \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f *\/   initialize_aggregates(aggstate, pergroups, numReset);   \/* \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438\u0437 \u0432\u0445\u043e\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 *\/   for (;;)   {      advance_aggregates(aggstate);      outerslot = fetch_input_tuple(aggstate);      if (TupIsNull(outerslot))      {         aggstate-&gt;agg_done = true;         break;      }   }   \/* \u0412\u044b\u0437\u043e\u0432 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 *\/   finalize_aggregates(aggstate, peragg, pergroups[currentSet]);      return project_aggregates(aggstate);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 1-\u043a-1 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 (\u0435\u0433\u043e \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434) \u0432\u044b\u0448\u0435. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u0440\u0442\u0435\u0436 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432\u0445\u043e\u0434 \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0439, \u0430 \u0437\u0430\u0447\u0435\u043c \u0438\u043c\u0435\u043d\u043d\u043e &#8212; \u0443\u0432\u0438\u0434\u0438\u043c \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>\u0414\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u0438\u0437 \u043f\u043e\u0434\u0443\u0437\u043b\u0430 \u0432 \u044d\u0442\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>fetch_input_tuple<\/code>. \u041f\u043e\u043a\u0430 \u043d\u0430\u043c \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438, \u0438 \u0447\u0438\u0442\u0430\u0435\u043c \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438\u0437 \u043f\u043e\u0434-\u0443\u0437\u043b\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>SeqScan<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c, \u043d\u0443\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>initialize_aggregates<\/code>. \u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/executor\/nodeAgg.h#L250 *\/struct AggStatePerGroupData{    Datum  transValue;        \/* current transition value *\/    bool   transValueIsNull;    bool   noTransValue;      \/* true if transValue not set yet *\/};<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>AggStatePerGroup<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430. \u041e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438.<\/p>\n<p>\u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u0434\u0432\u0430 \u043f\u043e\u043b\u044f: \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 <code>NULL<\/code>, \u043d\u043e \u0435\u0441\u0442\u044c \u0438 \u0442\u0440\u0435\u0442\u0438\u0439 &#8212; \u0444\u043b\u0430\u0433 <code>noTransValue<\/code>. \u0414\u0435\u043b\u043e \u0432 \u043d\u044e\u0430\u043d\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 <code>NULL<\/code>\u2019\u0430\u043c\u0438, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b \u0440\u0430\u043d\u0435\u0435, &#8212; \u0435\u0441\u043b\u0438 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 <code>NULL<\/code>, \u0442\u043e \u043f\u0435\u0440\u0432\u043e\u0435 \u043d\u0435 <code>NULL<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u043d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0444\u043b\u0430\u0433 &#8212; \u043a\u0430\u043a \u0442\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0442\u044c <code>NULL<\/code>, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435, \u043e\u0442 <code>NULL<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0440\u043d\u0443\u043b\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u043b\u0430\u0433.<\/p>\n<p>\u041d\u043e \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0430 \u0441\u0430\u043c\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0434\u0432\u0443\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u0445 &#8212; <code>AggStatePerTrans<\/code> \u0438 <code>AggStatePerAgg<\/code>.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/82d\/5a4\/fa0\/82d5a4fa0fc01e1828aef6d6c6c99935.png\" alt=\"\u0412\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u044c PerTrans \u0438 PerAgg \u0441 \u043b\u043e\u0433\u0438\u043a\u043e\u0439\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/82d\/5a4\/fa0\/82d5a4fa0fc01e1828aef6d6c6c99935.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/82d\/5a4\/fa0\/82d5a4fa0fc01e1828aef6d6c6c99935.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0412\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u044c PerTrans \u0438 PerAgg \u0441 \u043b\u043e\u0433\u0438\u043a\u043e\u0439<\/figcaption><\/div>\n<\/figure>\n<blockquote>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0432\u0435\u043b\u0438\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0445 \u043f\u043e\u043b\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u044f \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0436\u0443, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043b\u044f. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0432\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/972c14fb9134fdfd76ea6ebcf98a55a945bbc988\/src\/include\/executor\/nodeAgg.h#L30\">PerTrans<\/a> \u0438 \u043d\u0430 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/972c14fb9134fdfd76ea6ebcf98a55a945bbc988\/src\/include\/executor\/nodeAgg.h#L187\">PerAgg<\/a>.<\/p>\n<\/blockquote>\n<p><code>AggStatePerTrans<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430, \u043d\u043e \u0432\u043e\u0442 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 &#8212; <code>AggStatePerAgg<\/code>. \u0421\u0434\u0435\u043b\u0430\u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a, \u0430 \u0432 \u0443\u0433\u043e\u0434\u0443 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"sql\">SELECT agginitval, aggtransfn, count(*) cnt FROM pg_aggregate GROUP BY 1, 2 HAVING count(*) &gt; 1 ORDER BY 3 DESC;  agginitval   |          aggtransfn          | cnt ---------------+------------------------------+----- {0,0,0,0,0,0} | float8_regr_accum            |  11 {0,0,0}       | float4_accum                 |   7               | ordered_set_transition       |   7 {0,0,0}       | float8_accum                 |   7               | int4_accum                   |   6               | numeric_accum                |   6               | int2_accum                   |   6               | int8_accum                   |   6               | ordered_set_transition_multi |   4               | interval_avg_accum           |   2               | numeric_avg_accum            |   2               | int8_avg_accum               |   2               | booland_statefunc            |   2(13 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u0441\u044e\u0434\u0430 \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0432 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u043c\u0438, \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043a\u043e\u043f\u0438\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u041d\u0435\u0437\u0430\u0447\u0435\u043c \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0438 \u043c\u0435\u0441\u0442\u043e, \u0438 \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f \u043d\u0438\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0438 \u0445\u0440\u0430\u043d\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e 1 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e, \u0430 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043d\u044b\u0435 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u043d\u0430\u0434 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c.<\/p>\n<pre><code class=\"sql\">SELECT avg(a::float), stddev(a::float) FROM tbl;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: <code>avg<\/code> \u0438 <code>stddev<\/code>. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u0432\u0435 (<code>numaggs<\/code>), \u043d\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e (<code>numtrans<\/code>).<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/74c\/6f5\/fe9\/74c6f5fe94ed72d80c9ad982cdb5a021.png\" alt=\" \u0438  \u043d\u0435 \u0440\u0430\u0432\u043d\u044b \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/74c\/6f5\/fe9\/74c6f5fe94ed72d80c9ad982cdb5a021.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/74c\/6f5\/fe9\/74c6f5fe94ed72d80c9ad982cdb5a021.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption> \u0438  \u043d\u0435 \u0440\u0430\u0432\u043d\u044b \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L629 *\/static voidinitialize_aggregate(AggState *aggstate, AggStatePerTrans pertrans,                     AggStatePerGroup pergroupstate){    if (pertrans-&gt;initValueIsNull)        pergroupstate-&gt;transValue = pertrans-&gt;initValue;    else        pergroupstate-&gt;transValue = datumCopy(pertrans-&gt;initValue,                                              pertrans-&gt;transtypeByVal,                                              pertrans-&gt;transtypeLen);    pergroupstate-&gt;transValueIsNull = pertrans-&gt;initValueIsNull;    pergroupstate-&gt;noTransValue = pertrans-&gt;initValueIsNull;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043b\u043e\u0433\u0438\u043a\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044f\u0441\u043d\u0430: \u0438\u0437 <code>AggStatePerTrans<\/code> \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 <code>AggStatePerGroup<\/code> &#8212; \u0441\u0430\u043c\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0434\u0432\u0430 \u0444\u043b\u0430\u0433\u0430.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430, \u043d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 \u043c\u044b \u0443\u0436\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b\u0438, \u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 <code>advance_aggregates<\/code>, \u043d\u043e \u0435\u0441\u043b\u0438 \u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u044c, \u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u043c.<\/p>\n<p>\u041c\u043d\u043e\u0433\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 PostgreSQL \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0435 \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u0412 Postgres \u044d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u0423 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 jit\u2019\u0430. \u0415\u0449\u0435 \u043e\u0434\u043d\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u043f\u043e\u0437\u0436\u0435, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c 2 \u043a\u043e\u043c\u0430\u043d\u0434\u044b: \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u0438 \u0432\u044b\u0437\u043e\u0432 \u0441\u0430\u043c\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u0415\u0441\u043b\u0438 \u0441\u043f\u0443\u0441\u0442\u0438\u043c\u0441\u044f \u0435\u0449\u0435 \u0440\u0430\u0437 \u0432\u043d\u0443\u0442\u0440\u044c, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c \u0438 \u0441\u0430\u043c\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execExprInterp.c#L643 *\/static Datum ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull){    EEO_SWITCH()    {       EEO_CASE(EEOP_OUTER_FETCHSOME)       {           slot_getsomeattrs(outerslot, op-&gt;d.fetch.last_var);           EEO_NEXT();       }       EEO_CASE(EEOP_AGG_PLAIN_TRANS_BYVAL)       {           AggState   *aggstate = castNode(AggState, state-&gt;parent);           AggStatePerTrans pertrans = op-&gt;d.agg_trans.pertrans;           AggStatePerGroup pergroup = &amp;aggstate-&gt;all_pergroups[op-&gt;d.agg_trans.transno];           ExecAggPlainTransByVal(aggstate, pertrans, pergroup,                                  op-&gt;d.agg_trans.aggcontext);           EEO_NEXT();       }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f <code>avg<\/code> \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 &#8212; <code>int4_avg_accum<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0442\u043e \u043e\u043d\u043e \u0432\u0441\u0435 \u043f\u043e \u043d\u0443\u043b\u044f\u043c (\u0441\u043b\u0435\u0432\u0430 \u0432\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0435) &#8212; <code>count<\/code> \u0438 <code>sum<\/code>. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0430\u043c \u043f\u043e\u0434\u0430\u043b\u0438 \u0447\u0438\u0441\u043b\u043e <code>1<\/code> (\u043f\u043e\u043b\u0435 <code>newval<\/code>), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435 &#8212; <code>count<\/code> \u0438 <code>sum<\/code> \u0440\u0430\u0432\u043d\u044b 1.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/637\/489\/c70\/637489c704db2831b72577086939cda6.gif\" alt=\"\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/637\/489\/c70\/637489c704db2831b72577086939cda6.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/637\/489\/c70\/637489c704db2831b72577086939cda6.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 <\/figcaption><\/div>\n<\/figure>\n<p>\u042d\u0442\u043e \u0431\u044b\u043b\u0430 \u043e\u0434\u043d\u0430 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f &#8212; \u0447\u0442\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u041c\u044b \u0442\u0430\u043a \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438. \u041a\u043e\u043d\u0435\u0446 \u0432\u0445\u043e\u0434\u0430 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u0443\u0437\u0435\u043b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>NULL<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0438\u0442\u0430\u0435\u043c \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c <code>NULL<\/code>.<\/p>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b. \u0417\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0443\u0436\u0435 \u043f\u0440\u043e\u0449\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043d\u0435\u0442, \u0438 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L1082 *\/static void finalize_aggregate(AggState *aggstate, AggStatePerAgg peragg,                               AggStatePerGroup pergroupstate,                               Datum *resultVal, bool *resultIsNull){    Datum result;    InitFunctionCallInfoData(*fcinfo, &amp;peragg-&gt;finalfn,                             numFinalArgs,                             pertrans-&gt;aggCollation,                             (Node *) aggstate, NULL);    *resultVal = FunctionCallInvoke(fcinfo);    *resultIsNull = fcinfo-&gt;isnull;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0436\u0435 <code>avg<\/code> \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 <code>int8_avg<\/code>. \u0412\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c, &#8212; \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u0443\u043c\u043c\u0443 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e, \u043d\u043e \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c, \u043c\u044b \u043e\u0431\u0430 \u0447\u0438\u0441\u043b\u0430 (<code>int<\/code>) \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043c \u043a \u0442\u0438\u043f\u0443 <code>numeric<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0443\u0436\u0435 \u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u0438\u0445 <code>numeric<\/code>\u2019\u043e\u0432.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/ab6\/7b9\/16c\/ab67b916c1e13079b69c2c4bb201b4ec.png\" alt=\"\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0434 \u043a\u043e\u043d\u0435\u0446\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/ab6\/7b9\/16c\/ab67b916c1e13079b69c2c4bb201b4ec.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/ab6\/7b9\/16c\/ab67b916c1e13079b69c2c4bb201b4ec.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0434 \u043a\u043e\u043d\u0435\u0446<\/figcaption><\/div>\n<\/figure>\n<blockquote>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u044d\u0442\u0438\u043c \u0442\u0438\u043f\u043e\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u0430, \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u0441\u0442\u0430\u0442\u044c\u0438. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/utils\/adt\/numeric.c#L3263\">numeric_div_opt_error<\/a>.<\/p>\n<\/blockquote>\n<h3>\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c<\/h3>\n<pre><code class=\"sql\">SELECT a, avg(b) FROM tbl GROUP BY a;          QUERY PLAN                  ------------------------ HashAggregate   Group Key: a   -&gt;  Seq Scan on tblSELECT a, b, c FROM tbl GROUP BY a, b, c;          QUERY PLAN                     ------------------------------- Group   Group Key: a, b, c   -&gt;  Sort         Sort Key: a, b, c         -&gt;  Seq Scan on tbl<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b \u0438\u0437\u043d\u0443\u0442\u0440\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. \u041d\u043e \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u043f\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 SQL \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>GROUP BY<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438. \u0412 Postgres \u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438: \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443.<\/p>\n<blockquote>\n<p>\u042d\u0442\u0443 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435\u0435 \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u043e\u0439 (\u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 SQL Server \u0438\u043b\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c GreenPlum, \u0433\u0434\u0435 \u0435\u0441\u0442\u044c \u0443\u0437\u0435\u043b Stream Aggregate), \u0442.\u043a. \u0441\u0430\u043c \u0443\u0437\u0435\u043b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442, \u0430 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u041d\u043e \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u201c\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443\u201d, \u0442.\u043a. \u0432 \u043a\u043e\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u043e\u0432\u043e \u201csort\u201d \u0438 \u043d\u0435\u0442 \u0434\u0430\u0436\u0435 \u0441\u043b\u043e\u0432\u0430 \u201cstream\u201d.<\/p>\n<\/blockquote>\n<h4>\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430<\/h4>\n<pre><code class=\"sql\">SELECT a, b FROM tbl GROUP BY a, b;                  QUERY PLAN       ---------------------------------------------- Group   Group Key: a, b   -&gt;  Sort         Sort Key: a, b         -&gt;  Seq Scan on tbl<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u0434\u0435\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c: \u0435\u0441\u043b\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0442\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043e\u0434\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0434\u0440\u0443\u0433 \u0437\u0430 \u0434\u0440\u0443\u0433\u043e\u043c, \u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u043d\u0435 \u0440\u0430\u0432\u043d\u044b\u0439 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u044d\u0442\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u0442. \u0412 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0432\u0441\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0445\u043e\u0434 (\u043f\u043e\u0442\u043e\u043a\u043e\u043c, \u0431\u0435\u0437 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f). \u041d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0443 (\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044f) \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u044b.<\/p>\n<p>\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442: \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u043a\u043e\u0440\u0442\u0435\u0436, \u0435\u0441\u043b\u0438 \u0440\u0430\u0432\u0435\u043d \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044e &#8212; \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 (\u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u043e\u0439 \u0436\u0435 \u0433\u0440\u0443\u043f\u043f\u044b), \u0438\u043d\u0430\u0447\u0435 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044f (\u043d\u043e\u0432\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430). \u0413\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438: \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e &#8212; \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 \u0441\u0440\u0430\u0437\u0443 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u0435\u043c, \u0438 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u043d\u0435\u0446 &#8212; \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/672\/a9b\/35b\/672a9b35be911a77ffcfe2b48398d202.gif\" alt=\"\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/672\/a9b\/35b\/672a9b35be911a77ffcfe2b48398d202.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/672\/a9b\/35b\/672a9b35be911a77ffcfe2b48398d202.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u042d\u0442\u043e \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"sql\">SELECT a, b, c FROM tbl GROUP BY a, b, c;           QUERY PLAN------------------------------- Group   Group Key: a, b, c   -&gt;  Sort         Sort Key: a, b, c         -&gt;  Seq Scan on tbl(5 rows) a | b | c ---+---+--- 1 | 1 | 1 1 | 1 | 2 1 | 2 | 1 2 | 2 | 1(4 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043a\u043e\u0434\u0443.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2264 *\/static TupleTableSlot *ExecAgg(PlanState *pstate){    AggState   *node = castNode(AggState, pstate);    TupleTableSlot *result = NULL;    if (!node-&gt;agg_done)    {        \/* Dispatch based on strategy *\/        switch (node-&gt;aggstrategy)        {            case AGG_HASHED:               \/* ... *\/            case AGG_MIXED:               \/* ... *\/            case AGG_PLAIN:            case AGG_SORTED:                return agg_retrieve_direct(node);        }    }    return NULL;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0436\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 <code>AGG_SORTED<\/code>, \u0438, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0412 \u043a\u0430\u043a\u043e\u043c-\u0442\u043e \u0441\u043c\u044b\u0441\u043b\u0435 \u043f\u043b\u043e\u0441\u043a\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0432\u044b\u0440\u043e\u0436\u0434\u0435\u043d\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043a\u0430\u043a \u0431\u044b \u0440\u0430\u0432\u043d\u044b, \u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>\u0415\u0449\u0435 \u043e\u0434\u043d\u0430 \u0432\u0430\u0436\u043d\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0438 \u0437\u0430\u0447\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436 \u043f\u0435\u0440\u0435\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0425\u043e\u0442\u044c \u043c\u044b \u0438 \u0441\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0438 \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 &#8212; \u043f\u043e\u0447\u0442\u0438 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435, \u043d\u043e \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0432\u0441\u0435 \u0436\u0435 \u0435\u0441\u0442\u044c, \u0438 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043e\u043d\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 SQL. \u041f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043a\u043e\u0440\u0442\u0435\u0436, \u0430 \u0434\u0440\u0443\u0433\u0438\u0435 &#8212; \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e (0+). \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0442\u043e \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0440\u0443\u0448\u0438\u0442\u044c \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0438 \u0442\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043f\u043e\u0439\u0434\u0435\u0442 \u043d\u0430\u043f\u0435\u0440\u0435\u043a\u043e\u0441\u044f\u043a (\u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u0435\u0440\u043d\u0443\u0442\u044c). \u0417\u0434\u0435\u0441\u044c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e, \u043a\u043e\u0433\u0434\u0430 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0441\u044f <code>agg_retrieve_direct<\/code> &#8212; \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u0447\u0438\u0442\u0430\u043b\u0438 \u043a\u043e\u0440\u0442\u0435\u0436 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b\u0438, \u0447\u0442\u043e \u043e\u043d \u043d\u0435 <code>NULL<\/code>, \u0442.\u0435. \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432 \u044d\u0442\u043e\u043c \u043d\u0435 \u0431\u044b\u043b\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0435\u0441\u0442\u044c &#8212; \u0435\u0441\u043b\u0438 \u0432\u0445\u043e\u0434 \u043f\u0443\u0441\u0442\u043e\u0439, \u0442\u043e \u0434\u043b\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c <code>NULL<\/code> (\u0442.\u0435. \u0432\u0445\u043e\u0434 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0441\u044f \u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442), \u0430 \u0434\u043b\u044f \u043f\u043b\u043e\u0441\u043a\u043e\u0439 &#8212; \u043e\u0434\u0438\u043d \u043a\u043e\u0440\u0442\u0435\u0436 \u0441 \u043a\u0430\u043a\u0438\u043c\u0438-\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 (\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0430\u0434 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u043d\u0438 \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c).<\/p>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0443\u0447\u0430\u0441\u0442\u043a\u0430 \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u043d\u0430 <code>NULL<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2498 *\/static TupleTableSlot *agg_retrieve_direct(AggState *aggstate){   Agg           *node = aggstate-&gt;phase-&gt;aggnode;   AggStatePerAgg peragg;   AggStatePerGroup *pergroups;   \/* \u0421\u0430\u043c\u044b\u0439 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u044b\u0437\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u0435\u043c *\/   if (aggstate-&gt;grp_firstTuple == NULL)   {      outerslot = fetch_input_tuple(aggstate);      if (TupIsNull(outerslot))      {         \/* \u041f\u0440\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0435 \u0441 \u043f\u0443\u0441\u0442\u044b\u043c \u0432\u0445\u043e\u0434\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c, \u043d\u043e \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0440\u043e\u0432\u043d\u043e 1 \u043a\u043e\u0440\u0442\u0435\u0436 *\/         if (node-&gt;aggstrategy != AGG_PLAIN)            return NULL;      }   }   \/* \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043a\u0430\u043a \u0440\u0430\u043d\u044c\u0448\u0435 *\/}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 <code>agg_retrieve_direct<\/code>, \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0443\u0432\u0438\u0434\u0435\u043b\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043a\u043e\u043d\u0446\u0435\u043d\u0442\u0440\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0438 &#8212; \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u0433\u0440\u0430\u043d\u0438\u0446 \u0433\u0440\u0443\u043f\u043f. \u0410 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u043d\u0430 \u0432\u043e\u0442 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u0435 &#8212; \u043a\u043e\u0433\u0434\u0430 \u0447\u0438\u0442\u0430\u0435\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u043a\u043e\u0440\u0442\u0435\u0436, \u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044e:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2573 *\/static TupleTableSlot *agg_retrieve_direct(AggState *aggstate){   \/* ... *\/   for (;;)   {      advance_aggregates(aggstate);      if (TupIsNull(outerslot))      {         aggstate-&gt;agg_done = true;         break;      }      \/* If we are grouping, check whether we've crossed a group boundary *\/      if (node-&gt;aggstrategy != AGG_PLAIN)      {         tmpcontext-&gt;ecxt_innertuple = firstSlot;         if (!ExecQual(aggstate-&gt;phase-&gt;eqfunctions[node-&gt;numCols - 1], tmpcontext))         {            aggstate-&gt;grp_firstTuple = ExecCopySlotHeapTuple(outerslot);            break;         }      }   }   \/* ... *\/}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043d\u0430 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u043e, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442. \u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c (<code>ExecQual<\/code>), \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 &#8212; \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0432\u043e\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u041d\u043e \u043e\u0442\u043a\u0443\u0434\u0430 \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0435\u0440\u0443\u0442\u0441\u044f? \u041a\u0430\u043a \u0438 \u0432\u0441\u0435\u0433\u0434\u0430 &#8212; \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430.<\/p>\n<p>\u0423 \u0442\u0438\u043f\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u0438 \u0432\u0441\u0435 \u044d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0438 \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u043d\u043e \u043c\u044b \u043e\u043f\u044f\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0432\u043e\u0434: \u0442\u0438\u043f\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0438\/\u0438\u043b\u0438 \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0438. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f B-tree \u0438 HASH \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432. \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430, \u043d\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e \u0443 \u043e\u0431\u043e\u0438\u0445 \u044d\u0442\u0438\u0445 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430 &#8212; \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0438\u0449\u0435\u043c \u0443 Btree, \u0430 \u0437\u0430\u0442\u0435\u043c, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043d\u0430\u0448\u043b\u0438, \u0443 HASH-\u0438\u043d\u0434\u0435\u043a\u0441\u0430.<\/p>\n<p>\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0442\u0438\u043f\u043e\u0432 \u0438 \u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b (\u0432 \u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0442\u0438\u043f\u0430) \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u0433\u043e\u0440\u044f\u0447\u0438\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0445\u043e\u0434\u0438\u0442\u044c \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433, \u044d\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u043a\u044d\u0448\u0435 \u0442\u0438\u043f\u043e\u0432. \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043d\u0435\u043c\u0443 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>lookup_type_cache<\/code>, \u0438 \u0432\u043e\u0442 \u0435\u0435 \u043a\u0443\u0441\u043e\u043a (\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u044b\u0439), \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u043f\u043e\u0438\u0441\u043a \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/utils\/cache\/typcache.c#L632 *\/TypeCacheEntry *lookup_type_cache(Oid type_id, int flags){   TypeCacheEntry *typentry;   if (flags &amp; (TYPECACHE_EQ_OPR | TYPECACHE_EQ_OPR_FINFO))   {      Oid eq_opr = InvalidOid;         \/* BTREE *\/      if (typentry-&gt;btree_opf != InvalidOid)          eq_opr = get_opfamily_member(typentry-&gt;btree_opf,                                       typentry-&gt;btree_opintype,                                       typentry-&gt;btree_opintype,                                       BTEqualStrategyNumber);      \/* HASH *\/      if (typentry-&gt;hash_opf != InvalidOid &amp;&amp; eq_opr == InvalidOid)          eq_opr = get_opfamily_member(typentry-&gt;hash_opf,                                       typentry-&gt;hash_opintype,                                       typentry-&gt;hash_opintype,                                       HTEqualStrategyNumber);   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0437\u044f\u0442\u044c \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430. \u0412\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f (\u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0434\u043b\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432) \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b <code>STRICT<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c <code>NULL<\/code>, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u0438\u0437 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u0432 <code>NULL<\/code> (\u0447\u0442\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a <code>FALSE<\/code>), \u043d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 <code>NULL<\/code> \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438, \u0442\u043e \u043e\u043d\u0438 \u0432\u0441\u0435 \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432 \u043e\u0434\u043d\u0443 \u0433\u0440\u0443\u043f\u043f\u0443, \u0445\u043e\u0442\u044f \u043f\u043e \u0438\u0434\u0435\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0432\u0441\u0435 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445.<\/p>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>IS NOT DISTINCT FROM<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0441 <code>NULL<\/code> \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>TRUE<\/code> \u0435\u0441\u043b\u0438 \u043e\u0431\u0430 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 <code>NULL<\/code> \u0438 <code>FALSE<\/code>, \u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e 1 \u0438\u0437 \u043d\u0438\u0445. \u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u0430\u0440\u0430\u0442\u043e\u0440 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0435\u0441\u043b\u0438 \u043e\u0431\u0430 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435. \u0414\u043b\u044f \u043d\u0435\u0435 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execExprInterp.c#L1481 *\/static Datum ExecInterpExpr(ExprState *state, ExprContext *econtext){   EEO_CASE(EEOP_NOT_DISTINCT)   {      if (left_isnull &amp;&amp; right_isnull)      {          *op-&gt;resvalue = true;      }      else if (left_isnull || right_isnull)      {          *op-&gt;resvalue = false;      }      else      {          *op-&gt;resvalue = eqfunction();      }   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<details class=\"spoiler\">\n<summary>\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u0432\u0445\u043e\u0434 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d, \u0442\u043e \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0431\u0443\u0434\u0443\u0442 \u0441\u0442\u0430\u0440\u0448\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b (\u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u043f\u0438\u0441\u043a\u0430), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043c\u044b \u043a\u043b\u0430\u0434\u0435\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441 \u043a\u043e\u043d\u0446\u0430: \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u0430 \u043f\u043e\u0442\u043e\u043c \u0438\u0434\u0435\u043c \u043a \u043d\u0430\u0447\u0430\u043b\u0443.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execExpr.c#L4526 *\/ExprState *ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, const TupleTableSlotOps *lops,                       const TupleTableSlotOps *rops, int numCols, const AttrNumber *keyColIdx,                       const Oid *eqfunctions, const Oid *collations, PlanState *parent){    \/*     * Start comparing at the last field (least significant sort key). That's     * the most likely to be different if we are dealing with sorted input.     *\/    for (int natt = numCols; --natt &gt;= 0;)    {       \/* \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0448\u0430\u0433\u043e\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 *\/    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u0430, \u0438 \u043c\u044b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e.<\/p>\n<h4>\u0425\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h4>\n<pre><code class=\"sql\">SELECT a, b FROM tbl GROUP BY a, b;      QUERY PLAN  ------------------------ HashAggregate   Group Key: a, b   -&gt;  Seq Scan on tbl<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e \u0432\u0441\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438: \u043a\u043b\u044e\u0447 &#8212; \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#8212; \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430. \u041f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438\u0434\u0435\u043c \u0432 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043f\u043e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 (\u0442.\u0435. \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f) \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440.<\/p>\n<p>\u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e: \u043d\u0435\u0445\u0432\u0430\u0442\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438. \u0412 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0435 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b, \u043d\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f <em>\u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b<\/em>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u043c \u043f\u043e\u043f\u0430\u0434\u0435\u0442\u0441\u044f. \u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u043c (\u0432 \u0445\u0443\u0434\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b). \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 (\u043c\u044f\u0433\u043a\u043e\u0435) \u043f\u0430\u043c\u044f\u0442\u0438 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <code>work_mem<\/code>, \u0430 \u0434\u043b\u044f \u0445\u0435\u0448\u0430 \u043c\u044b \u0434\u0430\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c <code>hash_mem_multiplier<\/code>, \u043d\u043e \u0434\u0430\u0436\u0435 \u0442\u0430\u043a \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0445\u0432\u0430\u0442\u0438\u0442\u044c. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a \u0434\u043b\u044f \u0438\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u0410 \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e, \u043d\u0430\u0434\u043e \u0437\u043d\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/214\/2f7\/615\/2142f76152c6841c0bfced1ecb9d07d3.png\" alt=\"\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/214\/2f7\/615\/2142f76152c6841c0bfced1ecb9d07d3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/214\/2f7\/615\/2142f76152c6841c0bfced1ecb9d07d3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/figcaption><\/div>\n<\/figure>\n<details class=\"spoiler\">\n<summary>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0421\u0430\u043c\u0430 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f &#8212; \u043e\u043d\u0430 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 <code>simplehash.h<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/62d6c7d3df6287f1bd83199c1a746e50d31571a0\/src\/include\/lib\/simplehash.h\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a>). \u0412\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u043c\u0443 \u043a\u043e\u0434\u0443 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0435\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c (<code>#include<\/code>) \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430. \u0425\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438, <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/62d6c7d3df6287f1bd83199c1a746e50d31571a0\/src\/backend\/executor\/execGrouping.c#L35\">\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0430\u043a<\/a>:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execGrouping.c#L35 *\/#define SH_PREFIX tuplehash#define SH_ELEMENT_TYPE TupleHashEntryData#define SH_KEY_TYPE MinimalTuple#define SH_KEY firstTuple#define SH_HASH_KEY(tb, key) TupleHashTableHash_internal(tb, key)#define SH_EQUAL(tb, a, b) TupleHashTableMatch(tb, a, b) == 0#define SH_SCOPE extern#define SH_STORE_HASH#define SH_GET_HASH(tb, a) a-&gt;hash#define SH_DEFINE#include \"lib\/simplehash.h\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0430 \u0447\u0442\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u044d\u0442\u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u044b &#8212; \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u0442\u0430\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0438\u0437 \u0438\u0445 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0430\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u044d\u0442\u043e\u043c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<\/p>\n<p>\u0421\u0430\u043c\u0430 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430 &#8212; \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0439 \u0430\u0434\u0440\u0435\u0441\u0430\u0446\u0438\u0435\u0439, \u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u0438\u0434\u043e\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0439 \u201c\u0440\u043e\u0431\u0438\u043d \u0433\u0443\u0434\u201d. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 &#8212; \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u043e\u0434\u0438\u043d \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439 \u0438\u0434\u0435\u043c \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u044f\u0447\u0435\u0439\u043a\u0443 \u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u044d\u0442\u0443 \u0434\u0440\u0443\u0433\u0443\u044e \u044f\u0447\u0435\u0439\u043a\u0443 \u0438\u0449\u0435\u043c \u043f\u043e\u0431\u043b\u0438\u0436\u0435. \u041d\u043e \u0437\u0434\u0435\u0441\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0445\u0435\u043c\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u044b\u0448\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u043f\u0438\u0441\u043a\u0430\u043c\u0438 (\u0437\u0430\u043a\u0440\u044b\u0442\u0430\u044f \u0430\u0434\u0440\u0435\u0441\u0430\u0446\u0438\u044f). \u041f\u043e \u0434\u0432\u0443\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u044f \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e: \u0442\u0430\u043a \u043f\u0440\u043e\u0449\u0435 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0430 \u043a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0447\u0435\u0442\u043a\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0431\u0430\u043a\u0435\u0442\u044b \u043d\u0430\u043c \u0435\u0449\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f.<\/p>\n<\/div>\n<\/details>\n<p>\u041a\u043e\u043d\u0446\u0435\u043f\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0430\u043a\u0435\u0442\u043e\u0432. \u0412 \u043a\u0430\u0436\u0434\u043e\u043c \u0431\u0430\u043a\u0435\u0442\u0435 \u043b\u0435\u0436\u0430\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0445\u0435\u0448\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043c\u0430\u0441\u043a\u0435 \u0440\u0430\u0432\u043d\u044b. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442:<\/p>\n<ol>\n<li>\n<p>\u0425\u0435\u0448\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u044e\u0447 (\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u043c\u0430\u0441\u043a\u0443 \u043a \u044d\u0442\u043e\u043c\u0443 \u0445\u0435\u0448\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0431\u0430\u043a\u0435\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u0418\u0434\u0435\u043c \u043f\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0431\u0430\u043a\u0435\u0442\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043a\u043b\u044e\u0447\u0438 \u043d\u0430 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430<\/p>\n<\/li>\n<\/ol>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c \u0445\u0435\u0448\u0430 \u0440\u0430\u0432\u043d\u0430, \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0441 \u043e\u0434\u043d\u0438\u043c\u0438 \u0438 \u0442\u0435\u043c\u0438 \u0436\u0435 \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u043c\u0443 \u0438 \u0442\u043e\u043c\u0443 \u0436\u0435 \u0431\u0430\u043a\u0435\u0442\u0443 (\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u0445 \u0445\u0435\u0448\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0440\u0430\u0432\u043d\u044b). \u041a\u043e\u0433\u0434\u0430 \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0438\u043b\u0430\u0441\u044c, \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u0443 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443 &#8212; \u043d\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0442.\u043a. \u0434\u043b\u044f \u0441\u0431\u0440\u043e\u0441\u0430 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u043d\u043e \u043d\u0435 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\/\u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>SERIALFUNC<\/code> \u0432 <code>CREATE AGGREGATE<\/code>). \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u043d\u0435\u0442, \u044d\u0442\u0430 \u0433\u0440\u0443\u043f\u043f\u0430 \u0432 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0438 \u043d\u0435 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u0430\u043c \u043a\u043e\u0440\u0442\u0435\u0436 \u043d\u0430 \u0434\u0438\u0441\u043a, \u0430 \u043f\u043e\u0442\u043e\u043c \u0435\u0449\u0435 \u0440\u0430\u0437 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u0437 \u0441\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438 \u043f\u043e\u0442\u043e\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u0437 \u043d\u0438\u0445 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u0442\u043e \u044d\u0442\u043e \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c\u0438, \u0442\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u0442\u0440\u0430\u0434\u0430\u0442\u044c &#8212; \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0435 \u0446\u0438\u043a\u043b\u043e\u0432 \u0437\u0430\u043f\u0438\u0441\u0438\/\u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u0430\u043c\u0438\u0445 \u0442\u0430\u0431\u043b\u0438\u0446.<\/p>\n<p>\u0422\u0443\u0442 \u043d\u0430\u043c \u0438 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u043d\u0430\u043d\u0438\u0435 \u043e\u0431 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u041e\u043d\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435, <em>\u043d\u0435\u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u0435\u0441\u044f<\/em> \u0431\u0430\u043a\u0435\u0442\u044b (\u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0445\u0435\u0448\u0430). \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0430\u043a\u043e\u0439 \u0431\u0430\u043a\u0435\u0442 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0438 \u043d\u0435 \u0431\u0435\u0441\u043f\u043e\u043a\u043e\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u043b\u0438.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043c \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0438\u0434\u0435\u0435 &#8212; \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441\u0431\u0440\u043e\u0441, \u0442\u043e \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043d\u0435\u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0445\u0435\u0448\u0430. \u0420\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0437 \u043a\u0430\u0436\u0434\u043e\u0439 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e <strong>\u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0449\u0443\u044e\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438<\/strong>. \u0412 \u043b\u0443\u0447\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044d\u0442\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0438\u043c \u0441\u0431\u0440\u043e\u0441\u043e\u043c \u043d\u0430 \u0434\u0438\u0441\u043a.<\/p>\n<p>\u041f\u043e-\u0445\u043e\u0440\u043e\u0448\u0435\u043c\u0443, \u043d\u0430\u0434\u043e \u0431\u044b \u0437\u043d\u0430\u0442\u044c \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438, \u043d\u043e \u0441 \u0442\u0430\u043a\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0434\u0432\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u041f\u0435\u0440\u0432\u0430\u044f \u0438 \u0441\u0430\u043c\u0430\u044f \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0430\u044f &#8212; \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c. \u041d\u043e \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0438 \u0437\u043d\u0430\u043b\u0438 \u0431\u044b, \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 &#8212; \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u0434\u0432\u043e\u0438\u0447\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u043e\u0439, \u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 &#8212; \u043e\u043a\u0440\u0443\u0433\u043b\u044f\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0434\u043e \u0441\u0442\u0435\u043f\u0435\u043d\u0438 2, \u0442\u043e\u0433\u0434\u0430 \u043c\u0430\u0441\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0431\u0438\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c. \u041d\u043e \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0438\u0442\u044c \u0443\u0441\u0438\u043b\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c, \u0447\u0442\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e, \u0438 \u0442\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c \u0446\u0435\u043b\u0435\u0432\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u043c\u044f\u0442\u0438 (\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u043e\u043e\u0431\u0449\u0435) \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u043d\u0430\u043c \u043e\u0431\u044a\u0435\u043c. \u042d\u0442\u0430 \u0438\u0434\u0435\u044f \u0438 \u043b\u0435\u0436\u0438\u0442 \u0432 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2101 *\/static int hash_choose_num_partitions(double input_groups, double hashentrysize,                                      int used_bits, int *log2_npartitions){   Size hash_mem_limit = get_hash_memory_limit();   double mem_wanted = input_groups * hashentrysize;   \/* make enough partitions so that each one is likely to fit in memory *\/   double dpartitions = 1 + (mem_wanted \/ hash_mem_limit);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0448\u0438\u0431\u0438\u0442\u044c\u0441\u044f (\u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0435 \u0442\u0430 \u0438\u043b\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445), \u0438 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0441\u0431\u0440\u043e\u0441. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043d\u043e\u0432\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0434\u0432\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u041f\u0435\u0440\u0432\u043e\u0435 &#8212; \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0442 \u0445\u0435\u0448\u0430 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043f\u043e\u043f\u0430\u043b\u0438 \u0432 \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e, \u0442\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u044b \u0445\u0435\u0448\u0435\u0439 \u044d\u0442\u0438\u0445 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u0440\u0430\u0432\u043d\u044b, \u0438 \u0438\u0445 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u043c\u0435\u0440\u0430 \u0431\u0430\u043a\u0435\u0442\u0430 \u0432 \u0445\u0435\u0448\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u043d\u0443\u044e \u043c\u0430\u0441\u043a\u0443, \u0430 \u043d\u0435 \u043f\u0440\u0435\u0444\u0438\u043a\u0441.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2990 *\/static voidhashagg_spill_init(HashAggSpill *spill, LogicalTapeSet *tapeset, int used_bits,                   double input_groups, double hashentrysize){   npartitions = hash_choose_num_partitions(input_groups, hashentrysize,                                            used_bits, &amp;partition_bits);   spill-&gt;shift = 32 - used_bits - partition_bits;   if (spill-&gt;shift &lt; 32)       spill-&gt;mask = (npartitions - 1) &lt;&lt; spill-&gt;shift;   else       spill-&gt;mask = 0;   \/* ... *\/}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0442\u043e\u0440\u043e\u0435 &#8212; \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430. \u041e\u043d\u0430 \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0443\u044e \u043e\u0446\u0435\u043d\u043a\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430, \u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439. \u041c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c, \u0447\u0442\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0435, \u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u043e\u0446\u0435\u043d\u043a\u0443 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0430\u043a\u0435\u0442\u043e\u0432, \u043d\u043e \u0440\u0430\u0437 \u0443\u0436 \u043c\u044b \u0437\u0434\u0435\u0441\u044c (\u043f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u043c \u0441\u0431\u0440\u043e\u0441\u0435), \u0442\u043e, \u0437\u043d\u0430\u0447\u0438\u0442, \u0441 \u043e\u0446\u0435\u043d\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043b\u0438\u0441\u044c \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f.<\/p>\n<p>\u0412\u044b\u0445\u043e\u0434 \u043e\u0434\u0438\u043d &#8212; \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 HyperLogLog. \u041e\u043d\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0445\u0435\u0448-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L3016 *\/static voidhashagg_spill_init(HashAggSpill *spill, LogicalTapeSet *tapeset, int used_bits,                   double input_groups, double hashentrysize){   npartitions = hash_choose_num_partitions(input_groups, hashentrysize,                                            used_bits, &amp;partition_bits);   for (int i = 0; i &lt; npartitions; i++)       initHyperLogLog(&amp;spill-&gt;hll_card[i], HASHAGG_HLL_BIT_WIDTH);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u0437\u0430\u043a\u0440\u044b\u0442\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043a\u043e\u0434\u0443, \u043a\u0430\u043a \u0438 \u0432\u0441\u0435\u0433\u0434\u0430, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430. \u0421\u0435\u0439\u0447\u0430\u0441 \u0443 \u043d\u0430\u0441 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0438 \u0437\u0430 \u043d\u0435\u0433\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 <code>AGG_HASHED<\/code>.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2256 *\/static TupleTableSlot *ExecAgg(PlanState *pstate){   AggState *node = castNode(AggState, pstate);   switch (node-&gt;aggstrategy)   {       case AGG_HASHED:           if (!node-&gt;table_filled)               agg_fill_hash_table(node);           result = agg_retrieve_hash_table(node);           break;       case AGG_MIXED:       case AGG_SORTED:       case AGG_PLAIN:           \/* ... *\/   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0430\u043c\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438: \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u0435\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u0431\u0435\u0437 \u0441\u0431\u0440\u043e\u0441\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2625 *\/static void agg_fill_hash_table(AggState *aggstate){   TupleTableSlot *outerslot;   for (;;)   {       outerslot = fetch_input_tuple(aggstate);       if (TupIsNull(outerslot))           break;       lookup_hash_entries(aggstate);       advance_aggregates(aggstate);   }   aggstate-&gt;table_filled = true;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c &#8212; \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b &#8212; \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430. \u0415\u0435 \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u0430: <code>fetch_input_tuple<\/code> &#8212; \u0447\u0442\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439, \u0430 <code>advance_aggregates<\/code> &#8212; \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 <code>lookup_hash_entries<\/code>.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2205 *\/static void lookup_hash_entries(AggState *aggstate){    AggStatePerHash perhash = aggstate-&gt;perhash;    TupleHashTable hashtable = perhash-&gt;hashtable;    bool isnew = false;    TupleHashEntry entry;    entry = LookupTupleHashEntry(hashtable, hashslot, &amp;isnew, &amp;hash);    if (isnew)        initialize_hash_entry(aggstate, hashtable, entry);    aggstate-&gt;pergroup = TupleHashEntryGetAdditional(hashtable, entry);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>AggStatePerHash<\/code>. \u0412 \u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430\u044f \u0434\u043b\u044f \u043d\u0435\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f: \u0441\u0430\u043c\u0430 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0438 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (\u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430).<\/p>\n<p>\u041d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0432 <code>LookupTupleHashEntry<\/code>. \u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0438\u0441\u043a \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0437\u0430 \u043e\u0434\u0438\u043d \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0412\u043d\u0443\u0442\u0440\u0438 &#8212; \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e: \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0445\u0435\u0448 \u043a\u043b\u044e\u0447\u0430, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e\u0438\u0441\u043a\u0430 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0445\u0435\u0448\u0435\u043c.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execGrouping.c#L420 *\/static uint32 TupleHashTableHash_internal(struct tuplehash_hash *tb, const MinimalTuple tuple){    uint32 hashkey = ExecEvalExpr(hashtable-&gt;tab_hash_expr, hashtable-&gt;exprcontext, &amp;isnull);    return murmurhash32(hashkey);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0445\u0435\u0448 \u0434\u043b\u044f \u043a\u043e\u0440\u0442\u0435\u0436\u0430. \u0415\u0433\u043e \u043c\u044b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0437 \u0432\u0441\u0435\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0445\u0435\u0448-\u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0442\u0438\u043f\u0430.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0441 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 &#8212; \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0442\u0438\u043f (\u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u043c\/\u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u043c \u0442\u0438\u043f\u0430\u043c: RECORD, ARRAY, RANGE \u0438 \u0442.\u0434.). \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043d\u043e\u0432\u0430 \u0438\u0434\u0435\u043c \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433: \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u044d\u0442\u043e \u043f\u0435\u0440\u0432\u0430\u044f \u043e\u043f\u043e\u0440\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0445\u0435\u0448 \u0438\u043d\u0434\u0435\u043a\u0441\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u043f\u043e\u0440\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0423 \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438, \u043a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435, \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f. \u0427\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0431\u0449\u0438\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u043b\u0435\u0433\u043a\u043e\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043e\u043f\u043e\u0440\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u043e\u0440\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0444\u0438\u0447\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.<\/p>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0445\u0435\u0448-\u0438\u043d\u0434\u0435\u043a\u0441 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u0423 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u043e\u043f\u043e\u0440\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/access\/hash.h#L355 *\/\/* * When a new operator class is declared, we require that the user supply * us with an amproc function for hashing a key of the new type, returning * a 32-bit hash value.  We call this the \"standard\" hash function.  We * also allow an optional \"extended\" hash function which accepts a salt and * returns a 64-bit hash value.  This is highly recommended but, for reasons * of backward compatibility, optional. * * When the salt is 0, the low 32 bits of the value returned by the extended * hash function should match the value that would have been returned by the * standard hash function. *\/#define HASHSTANDARD_PROC        1#define HASHEXTENDED_PROC        2#define HASHOPTIONS_PROC         3#define HASHNProcs               3<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u0435\u0440\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u201c\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e\u201d. \u041a\u0440\u043e\u043c\u0435 \u043d\u0435\u0435 \u0435\u0441\u0442\u044c \u201c\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u0430\u044f\u201d, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0430\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u0414\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 &#8212; \u044d\u0442\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 B+tree. \u0423 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0446\u0435\u043b\u044b\u0445 \u0448\u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/access\/nbtree.h#L717 *\/\/* *    When a new operator class is declared, we require that the user *    supply us with an amproc procedure (BTORDER_PROC) for determining *    whether, for two keys a and b, a &lt; b, a = b, or a &gt; b.  This routine *    must return &lt; 0, 0, &gt; 0, respectively, in these three cases. * *    To facilitate accelerated sorting, an operator class may choose to *    offer a second procedure (BTSORTSUPPORT_PROC).  For full details, see *    src\/include\/utils\/sortsupport.h. * *    To support window frames defined by \"RANGE offset PRECEDING\/FOLLOWING\", *    an operator class may choose to offer a third amproc procedure *    (BTINRANGE_PROC), independently of whether it offers sortsupport. *    For full details, see doc\/src\/sgml\/btree.sgml. * *    To facilitate B-Tree deduplication, an operator class may choose to *    offer a forth amproc procedure (BTEQUALIMAGE_PROC).  For full details, *    see doc\/src\/sgml\/btree.sgml. * *    An operator class may choose to offer a fifth amproc procedure *    (BTOPTIONS_PROC).  These procedures define a set of user-visible *    parameters that can be used to control operator class behavior.  None of *    the built-in B-Tree operator classes currently register an \"options\" proc. * *    To facilitate more efficient B-Tree skip scans, an operator class may *    choose to offer a sixth amproc procedure (BTSKIPSUPPORT_PROC).  For full *    details, see src\/include\/utils\/skipsupport.h. *\/#define BTORDER_PROC          1#define BTSORTSUPPORT_PROC    2#define BTINRANGE_PROC        3#define BTEQUALIMAGE_PROC     4#define BTOPTIONS_PROC        5#define BTSKIPSUPPORT_PROC    6#define BTNProcs              6<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u043e\u043f\u043e\u0440\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/access\/gist.h#L32\">GiST<\/a>, <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/access\/spgist.h#L23\">SP-GIST<\/a>, <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/access\/gin.h#L24\">GIN<\/a>.<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u043e \u044d\u0442\u043e \u0435\u0449\u0435 \u043d\u0435 \u0432\u0441\u0435. \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u0445\u0435\u0448 \u0432\u0435\u0440\u043d\u0443\u0442\u044c, \u043c\u044b <em>\u0435\u0449\u0435 \u0440\u0430\u0437 \u0435\u0433\u043e \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c<\/em>. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043f\u043b\u043e\u0445\u0438\u0445 \u0445\u0435\u0448-\u0444\u0443\u043d\u043a\u0446\u0438\u0439 &#8212; \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c \u043f\u043b\u043e\u0445\u0438\u0435 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0441\u0441\u0438\u043c\u0438\u0441\u0442\u0438\u0447\u043d\u043e \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c \u0445\u0435\u0448. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f murmurhash.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0438\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c \u0432 \u0441\u0430\u043c\u043e\u0439 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435. \u0417\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u0430\u043c\u043e\u0439 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0435\u0435 \u043e\u043f\u0443\u0441\u0442\u0438\u043c. \u0418\u0437 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u0430\u0434\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 (\u0435\u0441\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442). \u042d\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0432 <code>initialize_hash_entry<\/code>, \u0438 \u043f\u043e\u043a\u0430 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0442\u0443\u0442 \u043d\u0435\u0442 &#8212; \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043a\u0430\u043a \u0438 \u0431\u044b\u043b\u043e \u0440\u0430\u043d\u044c\u0448\u0435.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2136 *\/static void initialize_hash_entry(AggState *aggstate, TupleHashTable hashtable,                                  TupleHashEntry entry){   \/* ... \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u0434 \u0442\u0443\u0442 *\/   for (transno = 0; transno &lt; aggstate-&gt;numtrans; transno++)   {       AggStatePerTrans pertrans = &amp;aggstate-&gt;pertrans[transno];       AggStatePerGroup pergroupstate = &amp;pergroup[transno];       initialize_aggregate(aggstate, pertrans, pergroupstate);   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 &#8212; \u043d\u0430 \u0440\u0443\u043a\u0430\u0445, \u0438 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 <code>advance_aggregates<\/code>, \u043e\u0442\u043a\u0443\u0434\u0430 \u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0441\u0442 \u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u041d\u043e \u0435\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0435\u0435 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443, \u0442\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0443\u0437\u043b\u0430, \u0430 \u043d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430) \u0438 \u043a\u043e\u0440\u0442\u0435\u0436. \u042d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0447\u0435\u0440\u0435\u0437 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u0435 <code>pergroup<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 <code>AggStatePerGroup<\/code>, \u0430 \u043f\u043e\u0441\u043b\u0435 <code>advance_aggregates<\/code> \u043f\u043e\u0439\u043c\u0435\u0442, \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0440\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0441\u0442 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443.<\/p>\n<pre><code class=\"cpp\">static voidlookup_hash_entries(AggState *aggstate){   \/* ... *\/   aggstate-&gt;pergroup = TupleHashEntryGetAdditional(hashtable, entry);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0432 <code>advance_aggregates<\/code>, \u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u043a\u043e\u043d\u0447\u0435\u043d\u0430. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0442\u0430\u043a, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0432\u0435\u0441\u044c \u0432\u0445\u043e\u0434 \u0438, \u043a\u043e\u0433\u0434\u0430 \u0432\u0445\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043a \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u043f\u043e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u042d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/62d6c7d3df6287f1bd83199c1a746e50d31571a0\/src\/backend\/executor\/nodeAgg.c#L2859\"><code>agg_retrieve_hash_table_in_memory<\/code><\/a>, \u043d\u043e \u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\/\u043d\u0435\u0432\u0430\u0436\u043d\u043e, \u0430 \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043c\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2860 *\/static TupleTableSlot *agg_retrieve_hash_table_in_memory(AggState *aggstate){   for (;;)   {      TupleHashTable hashtable = perhash-&gt;hashtable;      TupleHashEntry entry;      entry = ScanTupleHashTable(hashtable, &amp;perhash-&gt;hashiter);      if (entry == NULL)          return NULL;      finalize_aggregates(aggstate, peragg, pergroup);      result = project_aggregates(aggstate);      if (result)          return result;   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0431\u044b\u043b\u0430 \u0441\u0430\u043c\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0447\u0430\u0441\u0442\u044c &#8212; \u043b\u043e\u0433\u0438\u043a\u0430 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043b\u0443\u0447\u0430\u044e, \u043a\u043e\u0433\u0434\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442.<\/p>\n<h4>\u0425\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0441\u0431\u0440\u043e\u0441 \u043d\u0430 \u0434\u0438\u0441\u043a<\/h4>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u0433\u0434\u0435 \u0438 \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043c \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438? \u0421\u0430\u043c\u043e\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043f\u0430\u043c\u044f\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0438\u043b\u0438. \u0422\u0430\u043a\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u043c\u044b \u0437\u043d\u0430\u0435\u043c &#8212; <code>initialize_hash_entry<\/code>, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b. \u0420\u0430\u043d\u0435\u0435 \u044f \u0441\u043a\u0430\u0437\u0430\u043b, \u0447\u0442\u043e \u201c\u043f\u043e\u043a\u0430 \u0442\u0430\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432\u201d, \u043d\u0430\u043c\u0435\u043a\u0430\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0438 \u0435\u0449\u0435 \u043a\u043e\u0435-\u0447\u0442\u043e. \u0418 \u044d\u0442\u0438\u043c \u0447\u0435\u043c-\u0442\u043e \u0435\u0449\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 &#8212; <code>hash_agg_check_limits<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>hash_agg_check_limits<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L1867 *\/static voidhash_agg_check_limits(AggState *aggstate){    uint64    ngroups = aggstate-&gt;hash_ngroups_current;    Size      meta_mem = MemoryContextMemAllocated(aggstate-&gt;hash_metacxt,                                                   true);    Size      entry_mem = MemoryContextMemAllocated(aggstate-&gt;hash_tablecxt,                                                    true);    Size      tval_mem = MemoryContextMemAllocated(aggstate-&gt;hashcontext-&gt;ecxt_per_tuple_memory,                                                   true);    Size      total_mem = meta_mem + entry_mem + tval_mem;    bool      do_spill = false;    \/*     * Don't spill unless there's at least one group in the hash table so we     * can be sure to make progress even in edge cases.     *\/    if (aggstate-&gt;hash_ngroups_current &gt; 0 &amp;&amp;        (total_mem &gt; aggstate-&gt;hash_mem_limit ||         ngroups &gt; aggstate-&gt;hash_ngroups_limit))    {        do_spill = true;    }    if (do_spill)        hash_agg_enter_spill_mode(aggstate);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0421\u0430\u043c\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430 &#8212; \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u043c\u044f\u0442\u0438 \u0432\u044b\u0434\u0435\u043b\u0438\u043b\u0438 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c <code>MemoryContext<\/code> \u0441 \u0442\u0435\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e. \u0418 \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442, \u0442\u043e \u043c\u044b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0435\u0436\u0438\u043c \u0441\u0431\u0440\u043e\u0441\u0430, spill mode.<\/p>\n<p>\u0420\u0435\u0436\u0438\u043c \u0441\u0431\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u043c \u0440\u0435\u0436\u0438\u043c\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0442 \u0444\u0430\u043a\u0442, \u0447\u0442\u043e \u043c\u044b \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a, \u043d\u043e \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u043f\u0430\u043c\u044f\u0442\u0438, \u0442\u043e \u0438 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u043c, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 <code>AggStatePerGroup<\/code> \u043c\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c. \u041e\u0431 \u044d\u0442\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c <code>advance_aggregates<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u043b \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 &#8212; \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c <code>NULL<\/code> \u0432 <code>pergroup<\/code>. \u041d\u043e \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b <em>\u043d\u0435<\/em> \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0441\u0431\u0440\u043e\u0441\u0430, \u0442\u043e \u043c\u043e\u0436\u0435\u043c \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e <code>NULL<\/code> \u0431\u044b\u0442\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u0435\u0433\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043c \u043a \u0435\u0449\u0435 \u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0443 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 &#8212; \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0443\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<p>\u041a \u0447\u0435\u043c\u0443 \u0432\u0441\u0435 \u0438\u0434\u0435\u0442 &#8212; \u0432\u044b, \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c, \u0443\u0436\u0435 \u0434\u043e\u0433\u0430\u0434\u0430\u043b\u0438\u0441\u044c. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430: \u043e\u0434\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 <code>NULL<\/code>, \u0434\u0440\u0443\u0433\u0430\u044f \u043d\u0435\u0442 &#8212; \u0434\u043b\u044f \u0440\u0435\u0436\u0438\u043c\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0438 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438 \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0431\u0435\u0437 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (\u0442.\u043a. \u0432\u0441\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438), \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441 <code>NULL<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439, \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043d\u0435\u0439.<\/p>\n<p>\u0417\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>ExecBuildAggTransCall<\/code> \u0438 \u043f\u0435\u0440\u0432\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043e\u043d \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442, &#8212; \u044d\u0442\u0430 \u0441\u0430\u043c\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 <code>NULL<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>ExecBuildAggTransCall<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execExpr.c#L4036 *\/static voidExecBuildAggTransCall(ExprState *state, AggState *aggstate, bool nullcheck){   \/* ... *\/   \/* add check for NULL pointer? *\/   if (nullcheck)   {       scratch-&gt;opcode = EEOP_AGG_PLAIN_PERGROUP_NULLCHECK;       scratch-&gt;d.agg_plain_pergroup_nullcheck.setoff = setoff;       \/* adjust later *\/       scratch-&gt;d.agg_plain_pergroup_nullcheck.jumpnull = -1;       ExprEvalPushStep(state, scratch);       adjust_jumpnull = state-&gt;steps_len - 1;   }   \/* ... *\/}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0431\u0435\u0437 \u0433\u0440\u0443\u043f\u043f\u044b \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043d\u0430 \u0434\u0438\u0441\u043a \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041d\u043e \u0438 \u0442\u0443\u0442 \u043d\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e. \u0423 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0441 \u0434\u0438\u0441\u043a\u043e\u043c, \u0435\u0441\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0435\u0441\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u0440\u0430\u0431\u043e\u0442\u044b:<\/p>\n<ol>\n<li>\n<p>\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u043a\u0430\u0442 \u0432 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 (\u0438 \u0441\u0430\u043c\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430)<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u0440\u0438 \u0432\u0441\u0435\u043c \u044d\u0442\u043e\u043c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u044b \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0447\u0438\u0442\u0430\u0435\u043c, \u0430 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u043a \u0443\u0436\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u0437\u0430\u043d\u043e\u0432\u043e \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f, \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0432 \u043f\u043e\u0442\u043e\u043a\u0435. \u041a \u043d\u0430\u043c (\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c) \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u043e: \u043f\u0440\u0438 \u0441\u0431\u0440\u043e\u0441\u0435 \u0447\u0438\u0442\u0430\u0442\u044c \u0437\u0430\u043d\u043e\u0432\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043d\u0430\u043c \u043d\u0435 \u043d\u0430\u0434\u043e, \u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043a\u0430\u0436\u0434\u0430\u044f \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u043e\u0436\u0434\u044b (\u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0441\u0431\u0440\u043e\u0441, \u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u0443\u044e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e).<\/p>\n<p>\u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 postgres \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/utils\/sort\/logtape.c#L187\">LogicalTapeSet<\/a> &#8212; \u044d\u0442\u043e \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u043d\u0430\u0434 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0444\u0430\u0439\u043b\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 LogicalTape (\u0447\u0438\u0442\u0430\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432). \u0415\u0434\u0438\u043d\u0438\u0446\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 &#8212; \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b &#8212; \u043d\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u0436\u0434\u044b\u0439 LogicalTape &#8212; \u044d\u0442\u043e \u0441\u0432\u044f\u0437\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446.<\/p>\n<p>\u0418\u0434\u0435\u044f LogicalTapeSet \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f: \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c LogicalTape\/\u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e, \u0442\u043e \u043e\u0442\u043c\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043a\u043b\u0430\u0434\u0435\u043c \u0435\u0435 \u0432 \u043f\u0443\u043b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0445. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 LogicalTape, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0447\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0435\u0446 \u0444\u0430\u0439\u043b\u0430 \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u043a\u0430\u0436\u0434\u044b\u0439 LogicalTape &#8212; \u044d\u0442\u043e \u043e\u0434\u043d\u0430 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044f.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/1b2\/6f7\/6bf\/1b26f76bf601e2752796dd205181aa8e.gif\" alt=\"\u0418\u0434\u0435\u044f LogicalTapeSet\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/1b2\/6f7\/6bf\/1b26f76bf601e2752796dd205181aa8e.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/1b2\/6f7\/6bf\/1b26f76bf601e2752796dd205181aa8e.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0418\u0434\u0435\u044f LogicalTapeSet<\/figcaption><\/div>\n<\/figure>\n<p>\u0418 \u0432-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u043d\u0443\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0442.\u0435. \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u0430\u043c\u0438\u0445 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>HashAggSpill<\/code>. \u0412 \u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 &#8212; \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, LogicalTape \u0438 \u0442.\u0434. \u042d\u0442\u043e \u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u043d\u0430\u0448 \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0431\u0440\u043e\u0441, \u0442\u043e \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043c\u044b \u0431\u0435\u0440\u0435\u043c \u043e\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 (<code>numGroups<\/code>), \u0430 <code>0<\/code> &#8212; \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0431\u0438\u0442\u043e\u0432 \u0445\u0435\u0448\u0430 (\u043f\u043e\u043a\u0430 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438).<\/p>\n<p>\u041f\u043e\u0434\u044b\u0442\u043e\u0436\u0438\u0432\u0430\u044f, \u0440\u0435\u0436\u0438\u043c \u0441\u0431\u0440\u043e\u0441\u0430 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ol>\n<li>\n<p>\u041f\u0435\u0440\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 <code>NULL<\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u0441\u0431\u0440\u043e\u0441\u0430 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u0441\u0447\u0435\u0442 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u0441\u0435 \u044d\u0442\u043e \u0438 \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>hash_agg_enter_spill_mode<\/code>:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L1911 *\/static void hash_agg_enter_spill_mode(AggState *aggstate){   aggstate-&gt;hash_spill_mode = true;   hashagg_recompile_expressions(aggstate, aggstate-&gt;table_filled, true);   aggstate-&gt;hash_tapeset = LogicalTapeSetCreate(true, NULL, -1);   HashAggSpill *spill = palloc(sizeof(HashAggSpill));   hashagg_spill_init(spill, aggstate-&gt;hash_tapeset, 0,                      perhash-&gt;aggnode-&gt;numGroups,                      aggstate-&gt;hashentrysize);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u0443\u0442 \u0437\u0430\u043c\u0435\u0442\u043d\u044b \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e \u0438 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0430\u0434\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u043b\u0430\u0433 <code>isnew<\/code>, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u043b\u0438 \u0444\u043b\u0430\u0433 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c <code>NULL<\/code> &#8212; \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u044d\u0442\u043e \u0432\u0438\u0434\u0438\u0442 \u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>NULL<\/code>.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2216 *\/static void lookup_hash_entries(AggState *aggstate){   TupleHashEntry entry;   uint32    hash;   bool      isnew = false;   bool     *p_isnew;   \/* if hash table already spilled, don't create new entries *\/   p_isnew = aggstate-&gt;hash_spill_mode ? NULL : &amp;isnew;   entry = LookupTupleHashEntry(hashtable, hashslot,                                p_isnew, &amp;hash);   if (entry != NULL)   {      \/* ... *\/   }   else   {      HashAggSpill *spill = &amp;aggstate-&gt;hash_spills;      TupleTableSlot *slot = aggstate-&gt;tmpcontext-&gt;ecxt_outertuple;      hashagg_spill_tuple(aggstate, spill, slot, hash);      pergroup = NULL;   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0441\u0431\u0440\u043e\u0441\u0430 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>hashagg_spill_tuple<\/code>, \u0438 \u0445\u043e\u0442\u044f \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f (\u0447\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 50 \u0441\u0442\u0440\u043e\u043a) \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432 \u043d\u0435\u0439 \u043f\u043e\u043b\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0434\u0435\u0442\u0430\u043b\u0435\u0439.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b\u0438 <code>EXPLAIN VERBOSE<\/code>, \u0442\u043e \u0437\u0430\u043c\u0435\u0447\u0430\u043b\u0438, \u0447\u0442\u043e \u043d\u0438\u0436\u0435\u043b\u0435\u0436\u0430\u0449\u0438\u0435 Scan \u0443\u0437\u043b\u044b \u043c\u043e\u0433\u0443\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043a\u043e\u0440\u0442\u0435\u0436\u0430, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c. \u041d\u0438\u0436\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u044f\u0440\u043a\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c &#8212; \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442 <code>a<\/code>, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u0442\u0440\u0438.<\/p>\n<pre><code class=\"sql\">EXPLAIN (VERBOSE) SELECT a FROM tbl GROUP BY a;           QUERY PLAN-------------------------------- HashAggregate   Output: a   Group Key: tbl.a   -&gt;  Seq Scan on public.tbl         Output: a, b, c(5 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041b\u0438\u0448\u043d\u0435\u0435 \u043c\u0435\u0441\u0442\u043e \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, \u043d\u043e \u0438 \u043b\u043e\u043c\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0442\u043e\u0436\u0435 (\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u043a\u043e\u0440\u0442\u0435\u0436\u0430, <code>TupleDesc<\/code>), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u0435\u0442\u0438\u043c <code>NULL<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0447\u0435\u043c\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u043e\u0442\u0432\u0435\u0442 &#8212; \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0430\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e 1 \u0430\u0442\u0440\u0438\u0431\u0443\u0442, \u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0439\u0442\u0435, \u0447\u0442\u043e \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043c\u044b \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u043c \u0446\u0435\u043b\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 \u0438 \u043d\u0430 \u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u044e (\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430) \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0442\u0440\u0430\u0447\u0435\u043d\u044b \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u043f\u0440\u0438\u0447\u0435\u043c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u0442\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430, \u0442.\u043a. \u044d\u0442\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043c\u044b (\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430) \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435, \u0430 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u0443\u043c\u043d\u0435\u0435 &#8212; \u0435\u0441\u043b\u0438 \u044d\u0442\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0438\u043a\u043e\u043c\u0443 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b, \u0442\u043e \u0438 \u0442\u0440\u043e\u0433\u0430\u0442\u044c \u0438\u0445 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u0438 \u043d\u0435\u0437\u0430\u0447\u0435\u043c \u043d\u0430 \u043d\u0438\u0445 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f. \u0414\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a \u0438\u043b\u0438 \u043d\u0435\u0442 &#8212; \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043b\u0430\u043d\u0430 \u0441\u043a\u0430\u043d\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>create_scan_plan<\/code>:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/optimizer\/plan\/createplan.c#L642 *\/static Plan *create_scan_plan(PlannerInfo *root, Path *best_path, int flags){   \/* ... *\/   if (use_physical_tlist(root, best_path, flags))   {      if (best_path-&gt;pathtype == T_IndexOnlyScan)      {         \/* For index-only scan, the preferred tlist is the index's *\/         tlist = copyObject(((IndexPath *) best_path)-&gt;indexinfo-&gt;indextlist);         \/*          * Transfer sortgroupref data to the replacement tlist, if          * requested (use_physical_tlist checked that this will work).          *\/         if (flags &amp; CP_LABEL_TLIST)            apply_pathtarget_labeling_to_tlist(tlist, best_path-&gt;pathtarget);      }      else      {         tlist = build_physical_tlist(root, rel);         if (tlist == NIL)         {            \/* Failed because of dropped cols, so use regular method *\/            tlist = build_path_tlist(root, best_path);         }         else         {            \/* As above, transfer sortgroupref data to replacement tlist *\/            if (flags &amp; CP_LABEL_TLIST)               apply_pathtarget_labeling_to_tlist(tlist, best_path-&gt;pathtarget);         }      }   }   else   {      tlist = build_path_tlist(root, best_path);   }   \/* ... *\/}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 <code>use_physical_tlist<\/code>. \u041f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u0435\u0435 \u043a\u043e\u0434 \u0442\u0443\u0442 \u043d\u0435 \u0431\u0443\u0434\u0443 (\u0432\u043e\u0442 <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/optimizer\/plan\/createplan.c#L865\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a>, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435), \u043d\u043e \u043e\u043f\u0438\u0448\u0443 \u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430: \u043a\u043e\u0433\u0434\u0430 <em>\u043d\u0443\u0436\u043d\u043e<\/em> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b:<\/p>\n<ul>\n<li>\n<p>\u041e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e \u0438\u0437: \u0442\u0430\u0431\u043b\u0438\u0446\u0430 (\u043e\u0431\u044b\u0447\u043d\u0430\u044f, \u043d\u0435 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u043c\u0430\u044f, \u0442.\u0435. \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f), \u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441, \u0444\u0443\u043d\u043a\u0446\u0438\u044f (\u0432\u043a\u043b\u044e\u0447\u0430\u044f SRF), <code>VALUES<\/code> \u0438\u043b\u0438 CTE<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 <code>CustomPath<\/code> (\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u044b\u0435 AM)<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u044d\u0442\u043e IndexOnlyScan, \u0442\u043e \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u044b \u0438\u0437 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e <\/p>\n<blockquote>\n<p>\u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0442\u0430\u043a. \u0414\u0430, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u043c\u0435\u0439\u043d\u0441\u0442\u0440\u0438\u043c\u043d\u043e\u043c Btree, \u0442\u043e \u043e\u043d\u043e \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043c\u043e\u0436\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c, \u043d\u043e \u0432 \u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f. \u041c\u043e\u0436\u043d\u043e \u0438\u043b\u0438 \u043d\u0435\u0442 \u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442 &#8212; \u0437\u0430 \u044d\u0442\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>amcanreturn<\/code> (\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c). \u0414\u043b\u044f Btree \u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/access\/nbtree\/nbtree.c#L1745\"><code>btcanreturn<\/code><\/a> \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>true<\/code>, \u043d\u043e \u0432\u043e\u0442 \u0443 \u0445\u0435\u0448- \u0438 \u0431\u043b\u0443\u043c-\u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435\u0442 \u0432\u043e\u0432\u0441\u0435 &#8212; \u043e\u043d\u0438 \u043d\u0438\u043a\u0430\u043a\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c, \u0430 \u0434\u043b\u044f GiST \u0444\u0443\u043d\u043a\u0446\u0438\u044f <a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/access\/gist\/gistget.c#L797\"><code>gistcanreturn<\/code><\/a> \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0441\u0432\u043e\u0438 \u043e\u043f\u043e\u0440\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<\/blockquote>\n<\/li>\n<li>\n<p>\u041d\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 NULLable \u0447\u0430\u0441\u0442\u0438 OUTER JOIN\u2019\u0430 (\u0442.\u0435. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0435 \u0441\u0442\u0430\u043d\u0435\u0442 NULL, \u0435\u0441\u043b\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 JOIN\u2019\u0430 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442) <\/p>\n<blockquote>\n<p>\u0427\u0435\u0441\u0442\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u0432\u0441\u0435 \u043f\u0443\u043d\u043a\u0442\u044b \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b, \u043a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0433\u043e. \u041d\u043e, \u043f\u043e\u0440\u0430\u0437\u043c\u044b\u0448\u043b\u044f\u0432, \u043f\u0440\u0438\u0448\u0435\u043b \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0432\u044b\u0432\u043e\u0434\u0443: \u0435\u0441\u043b\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f, \u0442\u043e \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0438\u0437 NULLable \u0447\u0430\u0441\u0442\u0438 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043d\u0443\u043b\u0438\u0442\u044c, \u043d\u043e \u043a\u0430\u043a \u043c\u044b \u0437\u0430\u043d\u0443\u043b\u0438\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435 \u0437\u043d\u0430\u043b\u0438 (\u0435\u0441\u043b\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0442\u0435\u043c\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435)? \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/blockquote>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c <code>HyperLogLog<\/code> \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0441\u0431\u0440\u043e\u0441\u0430. \u041d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438\u0434\u0443\u0442 \u0432 \u043e\u0434\u043d\u0443 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e, \u0442\u043e \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0438\u0445 \u0445\u0435\u0448\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439. \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0445\u044d\u0448 \u0432\u043e\u0442 \u0442\u0430\u043a \u0441\u0440\u0430\u0437\u0443, \u043e\u0446\u0435\u043d\u043a\u0430 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u043e\u0436\u0435\u0442 \u0443\u0445\u0443\u0434\u0448\u0438\u0442\u044c\u0441\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u0445\u0435\u0448 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c, \u043c\u044b \u0435\u0433\u043e \u0435\u0449\u0435 \u0440\u0430\u0437 \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c. \u041d\u043e \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043d\u0435 MurmurHash, \u0430 <code>lookup3<\/code> (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Jenkins_hash_function\">\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432 \u0432\u0438\u043a\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435<\/a>).<\/p>\n<blockquote>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u0435 \u0445\u0435\u0448-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 &#8212; \u043d\u0435 \u0437\u043d\u0430\u044e \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430, \u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u044e, \u0447\u0442\u043e \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e lookup3 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u0430\u044f, \u0447\u0435\u043c murmurhash.<\/p>\n<\/blockquote>\n<p>\u0412-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u0447\u0442\u043e\u0431\u044b \u043b\u0438\u0448\u043d\u0438\u0439 \u0440\u0430\u0437 \u043d\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0445\u0435\u0448-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043c\u044b \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438 \u0435\u0433\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0441\u0430\u043c\u0438\u043c \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u043c \u043d\u0430 \u0434\u0438\u0441\u043a.<\/p>\n<details class=\"spoiler\">\n<summary>hashagg_spill_tuple<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">static Sizehashagg_spill_tuple(AggState *aggstate, HashAggSpill *spill,                    TupleTableSlot *inputslot, uint32 hash){   TupleTableSlot *spillslot;   int             partition;   MinimalTuple tuple;   LogicalTape *tape;   int          total_written = 0;   \/*     * 1. \u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b    *\/   if (!aggstate-&gt;all_cols_needed)   {      spillslot = aggstate-&gt;hash_spill_wslot;      slot_getsomeattrs(inputslot, aggstate-&gt;max_colno_needed);      ExecClearTuple(spillslot);      for (int i = 0; i &lt; spillslot-&gt;tts_tupleDescriptor-&gt;natts; i++)      {         if (bms_is_member(i + 1, aggstate-&gt;colnos_needed))         {            spillslot-&gt;tts_values[i] = inputslot-&gt;tts_values[i];            spillslot-&gt;tts_isnull[i] = inputslot-&gt;tts_isnull[i];         }         else            spillslot-&gt;tts_isnull[i] = true;      }      ExecStoreVirtualTuple(spillslot);   }   else      spillslot = inputslot;   tuple = ExecFetchSlotMinimalTuple(spillslot);   \/*     * 2. \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443    *\/   if (spill-&gt;shift &lt; 32)      partition = (hash &amp; spill-&gt;mask) &gt;&gt; spill-&gt;shift;   else      partition = 0;   spill-&gt;ntuples[partition]++;                                               \/* \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 *\/   addHyperLogLog(&amp;spill-&gt;hll_card[partition], hash_bytes_uint32(hash));   tape = spill-&gt;partitions[partition];   \/*     * 3. \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u0440\u0442\u0435\u0436 \u0438 \u0435\u0433\u043e \u0445\u0435\u0448    *\/   LogicalTapeWrite(tape, &amp;hash, sizeof(uint32));   total_written += sizeof(uint32);   LogicalTapeWrite(tape, tuple, tuple-&gt;t_len);   total_written += tuple-&gt;t_len;   return total_written;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0431\u0440\u043e\u0441\u0430 \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c <code>NULL<\/code> \u0432 <code>pergroup<\/code>. \u0422\u043e\u0433\u0434\u0430 <code>advance_aggregates<\/code> \u044d\u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442 \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 \u0441\u0442\u0430\u043d\u0435\u0442.<\/p>\n<blockquote>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b, \u043a\u0430\u043a \u0438 \u044f, \u0437\u0430\u0434\u0430\u043b\u0438\u0441\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c, \u0447\u0442\u043e \u0441\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0430 \u043d\u0435 \u0440\u0435\u0436\u0438\u043c\u0430 \u0441\u0431\u0440\u043e\u0441\u0430, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0441\u0431\u0440\u043e\u0441\u0430, \u0431\u0443\u0434\u0435\u0442 SEGFAULT.<\/p>\n<\/blockquote>\n<p>\u042d\u0442\u043e \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043b\u043e\u0433\u0438\u043a\u0435 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u0420\u0430\u043d\u044c\u0448\u0435 \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u043b\u0438 \u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0443 \u043d\u0430\u0441 \u043d\u0430 \u0440\u0443\u043a\u0430\u0445 \u0435\u0441\u0442\u044c \u0441\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0434\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0432 <code>hashagg_finish_initial_spills<\/code> (\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0440\u0430\u043d\u0435\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u043b).<\/p>\n<p>\u041f\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0443 \u201c\u0437\u0430\u043f\u0435\u0447\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0435\u201d \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0431\u0440\u043e\u0441\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>HashAggSpill<\/code>, \u043d\u043e \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u043d\u0430 \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u0430: \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c\u0438, \u0441\u0430\u043c\u0438 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u0433\u0434\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c (\u0435\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435), \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043c\u0435\u0441\u0442\u0430 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0430 \u0438 \u0442.\u0434. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u0435\u043f\u0443\u0441\u0442\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c <code>HashAggBatch<\/code> (\u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u201c\u0431\u0430\u0442\u0447\u201d) &#8212; \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439 \u0432\u0441\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b: LogicalTape (\u043e\u0442\u043c\u043e\u0442\u0430\u043d\u043d\u044b\u0439 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f), \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u0430\u044f \u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c (\u0438\u0437 HyperLogLog) \u0438 \u0442.\u0434.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0434\u0435\u0442\u0430\u043b\u044c &#8212; \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u0430\u0442\u0447 \u043c\u044b \u043a\u043b\u0430\u0434\u0435\u043c \u0432 \u043e\u0434\u043d\u0443 \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u0431\u0430\u0442\u0447\u0438 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443. \u0412 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0443 \u043d\u0430\u0441 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u043d\u0435\u0445\u0432\u0430\u0442\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438, \u0438 \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0430 \u0434\u0438\u0441\u043a, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0438 \u043a\u043b\u0430\u0434\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0430\u0442\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u0430 \u0441\u0430\u043c\u0430\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u043f\u0443\u0441\u0442\u0435\u0435\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044e \u0442\u0430\u043a\u0443\u044e \u0441\u0445\u0435\u043c\u0443:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/31d\/72d\/615\/31d72d615aa549a448eff9009342bbd0.png\" alt=\"\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 HashAggregate\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/31d\/72d\/615\/31d72d615aa549a448eff9009342bbd0.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/31d\/72d\/615\/31d72d615aa549a448eff9009342bbd0.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 HashAggregate<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0445\u0435\u043c\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u0430, \u043d\u043e \u0438\u0437 \u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0432\u043e\u0434, \u0447\u0442\u043e \u0431\u0443\u0434\u0442\u043e \u0431\u044b \u0437\u0430 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u0434. \u042d\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043d\u0435 \u0442\u0430\u043a &#8212; \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f &#8212; <code>agg_refill_hash_table<\/code>. \u0415\u0435 \u043a\u043e\u0434 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u0435\u043d \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043f\u0440\u0438 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438, \u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u044b:<\/p>\n<ol>\n<li>\n<p>\u0427\u0442\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u0439\u043f\u0430 \u0434\u043b\u044f \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0435 \u0445\u0435\u0448-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0441\u0431\u0440\u043e\u0441\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u044d\u0442\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438: <code>used_bits<\/code> (\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0442\u043e\u0432 \u0445\u0435\u0448\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438) \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439, \u0430 <code>input_card<\/code> (\u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c) \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e HyperLogLog.<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>agg_refill_hash_table<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2743 *\/static bool agg_refill_hash_table(AggState *aggstate){   for (;;)   {      bool  isnew = false;      bool *p_isnew = aggstate-&gt;hash_spill_mode ? NULL : &amp;isnew;        \/*        * 1. \u0414\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0449\u0430\u044f \u0445\u0435\u0448 \u0441\u0440\u0430\u0437\u0443       *\/      tuple = hashagg_batch_read(batch, &amp;hash);      if (tuple == NULL)          break;      \/*        * 2. \u0425\u0435\u0448 \u043d\u0430 \u0440\u0443\u043a\u0430\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u0440\u0443\u0433\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0443\u044e \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u0445\u0435\u0448       *\/      entry = LookupTupleHashEntryHash(hashtable, hashslot, p_isnew, hash);      if (entry != NULL)      {         \/* \u0413\u0440\u0443\u043f\u043f\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 - \u043a\u043e\u0434 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043a\u0430\u043a \u0438 \u043f\u0440\u0438 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u0447\u0442\u0435\u043d\u0438\u0438 *\/         if (isnew)            initialize_hash_entry(aggstate, hashtable, entry);         aggstate-&gt;hash_pergroup = TupleHashEntryGetAdditional(hashtable, entry);         advance_aggregates(aggstate);      }      else      {         if (!spill_initialized)         {            spill_initialized = true;            hashagg_spill_init(&amp;spill, tapeset,                              \/*                                * 3. \u041f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c \u0441\u0431\u0440\u043e\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u0443\u044e                               *    \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0430\u0442\u0447\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443                               *\/                               batch-&gt;used_bits, batch-&gt;input_card,                               aggstate-&gt;hashentrysize);         }         \/* no memory for a new group, spill *\/         hashagg_spill_tuple(aggstate, &amp;spill, spillslot, hash);         aggstate-&gt;hash_pergroup = NULL;      }   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u0441\u043a\u0430\u0437\u0430\u0442\u044c &#8212; \u0432\u0441\u0435, \u0440\u0430\u0441\u0445\u043e\u0434\u0438\u043c\u0441\u044f, \u043d\u043e \u043d\u0435\u0442. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u043e\u0434\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u043f\u0440\u0435\u0434\u0432\u043a\u0443\u0448\u0430\u0442\u044c \u043f\u043e\u0434\u043b\u0438\u043d\u043d\u043e\u0435 \u0432\u0435\u0441\u0435\u043b\u044c\u0435.<\/p>\n<h3>\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: GROUPING SET, CUBE, ROLLUP<\/h3>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 SQL \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: GROUPING SETS, CUBE \u0438 ROLLUP. \u0418\u0445 \u0437\u0430\u043c\u044b\u0441\u0435\u043b \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043e\u043a (\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u043e \u0440\u0430\u0437\u043d\u044b\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c) &#8212; \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u0437\u0430\u0442\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u041d\u0435 \u0432\u0441\u0435 \u0437\u043d\u0430\u044e\u0442, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043e\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 &#8212; \u044d\u0442\u043e GROUPING SETS. \u041e\u043d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430. \u0414\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u0432 <a href=\"https:\/\/www.postgresql.org\/docs\/current\/queries-table-expressions.html#QUERIES-GROUPING-SETS\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a> \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440: \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043e\u0431\u0449\u0443\u044e \u0441\u0443\u043c\u043c\u0443 \u043f\u0440\u043e\u0434\u0430\u0436 \u043f\u043e \u0431\u0440\u0435\u043d\u0434\u0443, \u0440\u0430\u0437\u043c\u0435\u0440\u0443 (\u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438) \u0438 \u043e\u0431\u0449\u0438\u0435 \u043f\u0440\u043e\u0434\u0430\u0436\u0438.<\/p>\n<pre><code class=\"sql\">SELECT brand, size, sum(sales)   FROM items_sold   GROUP BY GROUPING SETS ((brand), (size), ());-- \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 brand | size | sum-------+------+----- Foo   |      |  30 Bar   |      |  20       | L    |  15       | M    |  35       |      |  50(5 rows)-- \u041f\u043b\u0430\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0430 - \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438          QUERY PLAN    ------------------------------ MixedAggregate   Hash Key: brand   Hash Key: size   Group Key: ()   -&gt;  Seq Scan on items_sold(5 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u0442\u043e\u0433\u043e, \u0432 \u044d\u0442\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0442\u0440\u0438 GROUPING SET\u2019\u0430: brand, size \u0438 \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430. \u0415\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0435\u0441\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435, \u043d\u043e \u0435\u0433\u043e \u043d\u0435\u0442 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439, \u0442\u043e \u0432 \u0432\u044b\u0432\u043e\u0434\u0435 \u043e\u043d <code>NULL<\/code>.<\/p>\n<blockquote>\n<p>\u041d\u0430\u0434\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c GROUPING SET \u0438 <code>GROUPING SETS<\/code>. \u041f\u0435\u0440\u0432\u043e\u0435 &#8212; \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 (\u043d\u0430\u0431\u043e\u0440 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u043e \u043d\u0438\u043c), \u0430 \u0432\u0442\u043e\u0440\u043e\u0435 &#8212; \u044d\u0442\u043e \u0443\u0436\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 SQL-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0414\u0430\u043b\u0435\u0435 \u044f \u0431\u0443\u0434\u0443 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u201c\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430\u201d \u0438\u043b\u0438 \u201cGROUPING SET\u201d &#8212; \u044d\u0442\u043e \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 (\u0447\u0442\u043e\u0431\u044b \u0434\u043e\u043b\u0433\u043e \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c, \u043c\u043e\u0433\u0443 \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0442\u044c \u0434\u043e GS)<\/p>\n<\/blockquote>\n<p>\u042d\u0442\u043e\u0442 \u0436\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e UNION ALL:<\/p>\n<pre><code class=\"sql\">-- brandSELECT brand, NULL, sum(sales)      FROM items_sold      GROUP BY brandUNION ALL-- sizeSELECT NULL, size, sum(sales)      FROM items_sold      GROUP BY sizeUNION ALL-- brand AND sizeSELECT NULL, NULL, sum(sales)      FROM items_sold      GROUP BY brand, size;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0436\u0435 \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 GROUPING SETS.<\/p>\n<p>ROLLUP &#8212; \u044d\u0442\u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e \u0432\u0441\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430\u043c \u0441\u043f\u0438\u0441\u043a\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 (\u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043f\u0443\u0441\u0442\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0443 &#8212; \u043f\u043b\u043e\u0441\u043a\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443).<\/p>\n<pre><code class=\"sql\">ROLLUP(a, b, c)-- \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043eGROUPING SETS(   (a, b, c),   (a, b),   (a),   ())<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u043c <code>GROUPING SETS<\/code> \u043d\u0430 \u044d\u0442\u043e\u0442 <code>ROLLUP<\/code>, &#8212; \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"sql\">SELECT brand, size, sum(sales)   FROM items_sold   GROUP BY ROLLUP (brand, size); brand | size | sum -------+------+-----       |      |  50 Foo   | M    |  20 Bar   | L    |   5 Bar   | M    |  15 Foo   | L    |  10 Foo   |      |  30 Bar   |      |  20(7 rows)         QUERY PLAN------------------------------- MixedAggregate   Hash Key: brand, size   Hash Key: brand   Group Key: ()   -&gt;  Seq Scan on items_sold(5 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f CUBE &#8212; \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e \u0432\u0441\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430\u043c (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Power_set\">power set<\/a>).<\/p>\n<pre><code class=\"sql\">CUBE(a, b, c)-- \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043eGROUPING SETS(    (a, b, c),    (a, b   ),    (a,    c),    (a      ),    (   b, c),    (   b   ),    (      c),    (       ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043f\u044f\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438:<\/p>\n<pre><code class=\"sql\">SELECT brand, size, sum(sales)   FROM items_sold   GROUP BY CUBE (brand, size);         QUERY PLAN    ------------------------------- MixedAggregate   Hash Key: brand, size   Hash Key: brand   Hash Key: size   Group Key: ()   -&gt;  Seq Scan on items_sold(6 rows) brand | size | sum -------+------+-----       |      |  50 Foo   | M    |  20 Bar   | L    |   5 Bar   | M    |  15 Foo   | L    |  10 Foo   |      |  30 Bar   |      |  20       | L    |  15       | M    |  35(9 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u043d\u0444\u043b\u0438\u043a\u0442 CUBE \u0438 cube<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412 postgres \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 <a href=\"https:\/\/www.postgresql.org\/docs\/current\/cube.html\">cube<\/a> \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u043d\u043e\u0433\u043e\u043c\u0435\u0440\u043d\u044b\u043c\u0438 \u043a\u0443\u0431\u0430\u043c\u0438 (\u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435\/\u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0438 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043e\u0432\/\u043a\u0443\u0431\u043e\u0432 \u0438 \u0442.\u0434.). \u0412\u043e\u0442 \u0434\u0432\u0430 \u0444\u0430\u043a\u0442\u0430:<\/p>\n<ol>\n<li>\n<p>\u0412 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0438 \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>cube<\/code> &#8212; \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0442\u0438\u043f\u0430<\/p>\n<\/li>\n<li>\n<p>\u042d\u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u043e \u0435\u0449\u0435 <em>\u0434\u043e<\/em> \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f GS (\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c <a href=\"https:\/\/github.com\/postgres\/postgres\/commit\/9892ddf5ee0c1c82e879f4bb20bf1f53b4241a45\">25 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434<\/a>, \u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 GS &#8212; <a href=\"https:\/\/github.com\/postgres\/postgres\/commit\/f3d3118532175541a9a96ed78881a3b04a057128\">10 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434<\/a>)<\/p>\n<\/li>\n<\/ol>\n<p>\u0418\u0437 \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u044b\u0432\u043e\u0434 &#8212; \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 GS \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0443\u0441\u0438\u043b\u0438\u0439, \u0442.\u043a. <code>GROUP BY CUBE(...)<\/code> \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u044b\u043c.<\/p>\n<p>\u0420\u0435\u0448\u0438\u043b\u0438 \u044d\u0442\u043e \u0442\u0430\u043a: <code>CUBE<\/code>, <code>ROLLUP<\/code> \u0438 <code>GROUPING SETS<\/code> \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043d\u0435\u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438 (unreserved keywords) &#8212; \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>cube<\/code>). \u041d\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0435\u0449\u0435 \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 <code>CUBE()<\/code> \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f GS, \u0430 \u043d\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f. \u0422\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0445\u0430\u043a \u043f\u0430\u0440\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"cpp\">\/* * ... *  * To support CUBE and ROLLUP in GROUP BY without reserving them, we give them * an explicit priority lower than '(', so that a rule with CUBE '(' will shift * rather than reducing a conflicting rule that takes CUBE as a function name. * Using the same precedence as IDENT seems right for the reasons given above. * * ... *\/<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0445\u0430\u043a &#8212; \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u0430\u043c \u0434\u043b\u044f GS, \u043d\u043e \u0438\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u043d\u0438\u0445 \u0441\u0442\u0430\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u0448\u0435, \u0447\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f:<\/p>\n<pre><code>\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/parser\/gram.y#L13480 *\/group_by_item:            a_expr                                   { $$ = $1; }            | empty_grouping_set                     { $$ = $1; }            | cube_clause                            { $$ = $1; }            | rollup_clause                          { $$ = $1; }            | grouping_sets_clause                   { $$ = $1; }        ;\/* * These hacks rely on setting precedence of CUBE and ROLLUP below that of '(', * so that they shift in these rules rather than reducing the conflicting * unreserved_keyword rule. *\/rollup_clause:            ROLLUP '(' expr_list ')'                {                    $$ = (Node *) makeGroupingSet(GROUPING_SET_ROLLUP, $3, @1);                }        ;cube_clause:            CUBE '(' expr_list ')'                {                    $$ = (Node *) makeGroupingSet(GROUPING_SET_CUBE, $3, @1);                }        ;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<blockquote>\n<p>\u041f\u0440\u0438\u0437\u043d\u0430\u044e\u0441\u044c, \u044f \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043c\u043e\u0433\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044f\u0445, \u0438\u0437 \u0447\u0435\u0433\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0445\u0430\u043a \u0441\u043e\u0441\u0442\u043e\u0438\u0442.<\/p>\n<\/blockquote>\n<\/div>\n<\/details>\n<p>\u041c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u0441\u0435 \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e GROUPING SETS. \u0418, \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044e, \u043e\u0431\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435: \u0435\u0441\u043b\u0438 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043d\u0435\u0442 GROUPING SETS, \u0442\u043e \u044d\u0442\u043e \u0432\u044b\u0440\u043e\u0436\u0434\u0435\u043d\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 GS \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u044d\u0442\u0438 \u0434\u0432\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b \u0438 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u043f\u043b\u0430\u043d\u044b:<\/p>\n<pre><code class=\"sql\">EXPLAIN SELECT a, b FROM tbl GROUP BY a, b;EXPLAIN SELECT a, b FROM tbl GROUP BY GROUPING SETS((a, b));      QUERY PLAN------------------------ HashAggregate   Group Key: a, b   -&gt;  Seq Scan on tbl(3 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0443, \u0430 \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430, \u0431\u0435\u0437 GROUP BY, \u0442\u043e (\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e) \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0437\u0430\u043f\u0440\u043e\u0441 <code>GROUP BY ()<\/code> \u0438 \u0437\u0430\u0442\u0435\u043c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0432 <code>GROUP BY GROUPING SETS(())<\/code>. \u042d\u0444\u0444\u0435\u043a\u0442 \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0435: \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044e\u0442\u0441\u044f GROUPING SETS \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0435\u043a\u0430\u0440\u0442\u043e\u0432\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u043e\u043d\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435, \u0442\u043e \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0430\u0435\u043c \u0432\u0441\u0435 GS, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044d\u0442\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u044e\u0442. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"sql\">EXPLAIN SELECT a, b FROM tbl GROUP BY   GROUPING SETS(a, b), ROLLUP(a, c);       QUERY PLAN------------------------- HashAggregate   Hash Key: a, c, b   Hash Key: a, c   Hash Key: a   Hash Key: a   Hash Key: b, a   Hash Key: b   -&gt;  Seq Scan on tbl(8 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043e\u0442 GROUPING SETS \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c <code>a<\/code> \u0438 <code>b<\/code>, \u0430 \u043e\u0442 ROLLUP &#8212; <code>(a, c)<\/code>, <code>(a)<\/code> \u0438 <code>()<\/code>. \u0415\u0441\u043b\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u044d\u0442\u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0438\u043c &#8212; \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u043e, \u0447\u0442\u043e \u0434\u0430\u043b \u043d\u0430\u043c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a:<\/p>\n<pre><code>                         (a, c)(a  )       (a, c)       (a)        x   (a)      =   (a)(  b)       ()           (b, a, c)                         (b, a)                         (b)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u044b \u0441\u0440\u0430\u0437\u0443 \u0443\u0434\u0430\u043b\u0438\u043b\u0438 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0439 <code>()<\/code>, \u0442.\u043a. \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0432 \u043d\u0435\u043c \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430. \u0422\u0430\u043a\u0436\u0435 \u0443\u0434\u0430\u043b\u0438\u043b\u0438 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0435\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e GS, \u0442.\u043a. \u0432 \u043d\u0438\u0445 \u0442\u043e\u0436\u0435 \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430. \u041c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0430\u043c\u0438 &#8212; \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0440\u0430\u0432\u043d\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u0414\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0435\u0441\u044f GS<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0418\u0437-\u0437\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f \u0443 \u043d\u0430\u0441 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u044b GS, \u043a\u0430\u043a \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441 <code>a<\/code> &#8212; \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u0434\u0432\u0430\u0436\u0434\u044b. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0432\u0441\u0435\u043c GS, \u043d\u043e \u0435\u0441\u043b\u0438 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u044b \u043d\u0435 \u043d\u0443\u0436\u043d\u044b, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>DISTINCT<\/code> \u0434\u043b\u044f <code>GROUP BY<\/code>:<\/p>\n<pre><code class=\"sql\">EXPLAIN SELECT a, b FROM tblGROUP BY DISTINCT   GROUPING SETS(a, b), ROLLUP(a, c);         QUERY PLAN                      --------------------------HashAggregate   Hash Key: a, c   Hash Key: a   Hash Key: b, a, c   Hash Key: b, a   Hash Key: b   -&gt;  Seq Scan on tbl(7 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0439\u0441\u044f <code>a<\/code> \u0443\u0434\u0430\u043b\u0435\u043d. \u0415\u0441\u043b\u0438 \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 &#8212; <code>ALL<\/code>. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u043f\u043e \u0432\u0441\u0435\u043c GS, \u0434\u0430\u0436\u0435 \u0441 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0430\u043c\u0438, \u0438 \u044d\u0442\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f, \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c GROUPING SETS \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438, \u043d\u043e CUBE \u0438 ROLLUP \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438, \u043d\u043e \u043d\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 GROUPING SETS (!!). \u041b\u0443\u0447\u0448\u0435 \u044d\u0442\u043e \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435:<\/p>\n<pre><code class=\"sql\">-- \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043eEXPLAIN a, b FROM tbl GROUP BY   GROUPING SETS(a, GROUPING SETS(a, b, GROUPING SETS(a, b)));-- \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e, \u0442.\u043a. \u0432\u043d\u0443\u0442\u0440\u0438 ROLLUP \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0433\u043e ROLLUPEXPLAIN a, b FROM tbl GROUP BY   ROLLUP(a, b, ROLLUP(a, b, c));<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u044d\u0442\u043e \u043d\u0435 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a &#8212; \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 SQL: <code>GROUPING SETS<\/code> \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 (\u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u0435\u0431\u044f), \u0430 <code>ROLLUP<\/code> \u0438 <code>CUBE<\/code> &#8212; \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b SELECT.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u0432\u0441\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 <code>GROUPING SETS<\/code>, \u0442\u043e \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0438\u0445 \u043a \u044d\u0442\u043e\u043c\u0443 \u0432\u0438\u0434\u0443, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043b\u043e\u0441\u043a\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0430\u0431\u043e\u0440\u0430 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043e\u043a. \u0422\u043e\u0433\u0434\u0430 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0443\u0447\u0438\u0442\u044c \u043d\u0430\u0448\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0441 \u043e\u0434\u043d\u0438\u043c GS, \u0430 \u0441 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<h4>\u0425\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\/GS<\/h4>\n<p>\u0422\u0443\u0442 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e &#8212; \u0443 \u043d\u0430\u0441 \u043d\u0430 \u0440\u0443\u043a\u0430\u0445 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043e\u043a, \u0438 \u043c\u044b \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u0435\u0440\u0432\u043e\u0439. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e GS \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0432\u043e\u044e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c\u0438 \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0430\u043c\u044f\u0442\u044c \u0443 \u0432\u0441\u0435\u0445 \u043e\u0431\u0449\u0430\u044f, \u0442\u043e \u0438 \u0440\u0435\u0436\u0438\u043c \u0441\u0431\u0440\u043e\u0441\u0430 \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0449\u0438\u043c &#8212; \u0435\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u043e\u0434\u0438\u043d \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u043d\u0435\u0433\u043e, \u0442\u043e \u0432\u043e\u0439\u0434\u0443\u0442 \u0438 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435.<\/p>\n<p>\u0414\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b, \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043e\u0434\u043d\u043e\u0439 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439, \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0446\u0438\u043a\u043b\u043e\u0432, \u0433\u0434\u0435 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443\/\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443. \u0422\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u0432\u0435\u0441\u044c \u043a\u043e\u0434 <em>\u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/em> \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0413\u043b\u0430\u0432\u043d\u044b\u043c \u043c\u0430\u0440\u043a\u0435\u0440\u043e\u043c \u0446\u0438\u043a\u043b\u043e\u0432, \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u043e \u0432\u0441\u0435\u043c GS, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u043e\u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0435\u0437\u0434\u0435 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>setno<\/code>.<\/p>\n<pre><code class=\"cpp\">static void lookup_hash_entries(AggState *aggstate){   for (int setno = 0; setno &lt; aggstate-&gt;num_hashes; setno++)   {       AggStatePerHash perhash = &amp;aggstate-&gt;perhash[setno];       entry = LookupTupleHashEntry(hashtable, hashslot, p_isnew, &amp;hash);       if (entry != NULL)       {           \/* ... *\/           pergroup[setno] = TupleHashEntryGetAdditional(hashtable, entry);       }       else       {           \/* ... *\/           pergroup[setno] = NULL;       }   }}static void hash_agg_enter_spill_mode(AggState *aggstate){   for (int setno = 0; setno &lt; aggstate-&gt;num_hashes; setno++)   {       AggStatePerHash perhash = &amp;aggstate-&gt;perhash[setno];       HashAggSpill *spill = &amp;aggstate-&gt;hash_spills[setno];       hashagg_spill_init(spill, aggstate-&gt;hash_tapeset, 0,                          perhash-&gt;aggnode-&gt;numGroups,                          aggstate-&gt;hashentrysize);   }}static void hashagg_finish_initial_spills(AggState *aggstate){   for (int setno = 0; setno &lt; aggstate-&gt;num_hashes; setno++)   {       HashAggSpill *spill = &amp;aggstate-&gt;hash_spills[setno];       hashagg_spill_finish(aggstate, spill, setno);   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c <code>AggStatePerHash<\/code> \u043f\u043e \u043d\u0443\u0436\u043d\u043e\u043c\u0443 \u0438\u043d\u0434\u0435\u043a\u0441\u0443 (\u0442.\u0435. \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430), \u0430 \u043f\u043e\u0441\u043b\u0435 \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f <code>advance_aggregates<\/code> \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0430\u043a\u0436\u0435 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u043e \u043d\u0443\u0436\u043d\u043e\u043c\u0443 \u0438\u043d\u0434\u0435\u043a\u0441\u0443.<\/p>\n<p>\u041e\u043f\u044f\u0442\u044c-\u0442\u0430\u043a\u0438, \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c \u0441\u0431\u0440\u043e\u0441\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438\u0433\u0440\u044b \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f. \u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u043a\u0430\u043a \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438? \u0415\u0441\u043b\u0438 \u043a\u0430\u0436\u0434\u044b\u0439, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u0433\u0440\u0443\u043f\u043f\u044b, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u0432 \u043e\u0434\u043d\u043e\u0439 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0442\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0438 \u0441 \u0438\u0445 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435\u043c (\u043a\u0430\u043a?). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e, \u0438 <code>HashAggSpill<\/code> (\u0430 \u0438\u0437 \u043d\u0438\u0445 <code>HashAggBatch<\/code>) \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430. \u042d\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0437\u0430\u043f\u0438\u0441\u0438, \u043d\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0441\u0438\u043b\u044c\u043d\u0435\u0435 \u044d\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043a\u043e\u0434. \u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438 <em>\u043f\u0435\u0440\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438<\/em> \u043c\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439, \u0430 \u043d\u0435 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 (\u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0448\u0435 \u043f\u043e\u0434\u0447\u0435\u0440\u043a\u043d\u0443\u043b, \u0447\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u0441\u0430\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0430 \u043d\u0435 \u0432\u0441\u0435\u0439). \u041a\u0430\u043a\u0443\u044e \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432 \u0441\u0430\u043c\u043e\u043c \u0431\u0430\u0442\u0447\u0435 (\u043e\u043d \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0440\u0443\u0434\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0443\u0442 \u043d\u0435\u0442).<\/p>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438, \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0435.<\/p>\n<h4>\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430\/GS<\/h4>\n<p>\u0421 \u043d\u0435\u0439 \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0423 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u0430\u0446\u0438\u0438 &#8212; \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 GS. \u041d\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0442\u0430\u043a\u043e\u0439 \u0442\u0440\u044e\u043a \u043d\u0435 \u043f\u0440\u043e\u043a\u0430\u0442\u0438\u0442, \u0442.\u043a. \u0440\u0430\u0437\u043d\u044b\u0435 GS \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b, \u0438 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043e\u043a. \u0422\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e GS \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e. \u041e\u0442 \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043d\u0435 \u0443\u0439\u0434\u0435\u043c \u043d\u0438\u043a\u0430\u043a. \u0418 \u0432\u0441\u0435 \u0436\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 ROLLUP.<\/p>\n<p>\u041e\u043d \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e GROUPING SETS, \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0443\u0434\u0430\u043b\u044f\u044f \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0443 \u0441 \u043a\u043e\u043d\u0446\u0430. \u0421\u0440\u0430\u0437\u0443 \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u0441\u044f \u044d\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u043f\u043e \u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u0435, \u0430 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0442.\u043a. \u044d\u0442\u043e <em>\u043f\u0440\u0435\u0444\u0438\u043a\u0441\u044b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/em>. \u041d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0437\u0430 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0445\u043e\u0434 \u043f\u043e \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u0433\u0440\u0443\u043f\u043f\u0443, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043d\u0435\u0440\u0430\u0432\u043d\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436. \u041f\u0440\u0438\u0447\u0435\u043c \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e, \u043a\u0430\u043a\u043e\u0439 \u0438\u043c\u0435\u043d\u043d\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f, \u0433\u043b\u0430\u0432\u043d\u043e\u0435 &#8212; \u0444\u0430\u043a\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0410 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u0438\u0434\u0435\u044e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 GROUPING SET\u2019\u043e\u0432, \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0432\u044b\u0432\u043e\u0434 (\u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0435): \u043a\u043e\u0433\u0434\u0430 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043f\u043e\u0434 \u043d\u043e\u043c\u0435\u0440\u043e\u043c N, \u0442\u043e \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043a\u043e\u043d\u0435\u0446 GS \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c N, \u0430 \u0442\u0430\u043a\u0436\u0435 <em>\u0432\u0441\u0435\u0445 \u0431\u043e\u043b\u044c\u0448\u0438\u0445<\/em>. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u044d\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0440\u0430\u043d\u0435\u0435.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/81e\/0c1\/e87\/81e0c1e87fcbae3353565ba9425117d7.png\" alt=\"\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f GS 3\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/81e\/0c1\/e87\/81e0c1e87fcbae3353565ba9425117d7.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/81e\/0c1\/e87\/81e0c1e87fcbae3353565ba9425117d7.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f GS 3<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0438 \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b (\u0442.\u0435. \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e 1 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0438\u0437 \u0442\u0440\u0435\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432), \u0442\u043e, \u043d\u0430\u0442\u044b\u043a\u0430\u044f\u0441\u044c \u043d\u0430 \u044d\u0442\u043e\u0442 \u043a\u043e\u0440\u0442\u0435\u0436, \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0433\u0440\u0443\u043f\u043f\u0443 <code>112<\/code> \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u0438 \u0433\u0440\u0443\u043f\u043f\u0443 <code>121<\/code>. \u041d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0434\u0432\u0430 GROUPING SET\u2019\u0430 &#8212; <code>ab<\/code> \u0438 <code>abc<\/code>. \u0422\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u0438\u043d GS \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c 2. \u0415\u0441\u043b\u0438 \u043c\u044b \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f GS 3 \u0438 \u043a\u0430\u043a-\u0431\u044b \u0432\u044b\u0447\u0435\u0440\u043d\u0435\u043c \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0439 \u0442\u0440\u0435\u0442\u0438\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f GS \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c 2.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/e6b\/91d\/017\/e6b91d017bdafe305fb0046fa88911e2.png\" alt=\"\u0412\u044b\u0447\u0435\u0440\u043a\u043d\u0443\u043b\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/e6b\/91d\/017\/e6b91d017bdafe305fb0046fa88911e2.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/e6b\/91d\/017\/e6b91d017bdafe305fb0046fa88911e2.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0412\u044b\u0447\u0435\u0440\u043a\u043d\u0443\u043b\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0432\u044b\u0447\u0435\u0440\u043a\u043d\u0435\u043c \u0435\u0449\u0435 \u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u044f \u0435\u0449\u0435 \u043d\u0435 \u043d\u0430\u0441\u0442\u0430\u043b\u043e, \u0438 \u0433\u0440\u0443\u043f\u043f\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0438 \u043e\u0434\u0438\u043d \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043d\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/c15\/18c\/4e2\/c1518c4e2193d32875355dedfb842418.png\" alt=\"\u0412\u044b\u0447\u0435\u0440\u043a\u043d\u0443\u043b\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/c15\/18c\/4e2\/c1518c4e2193d32875355dedfb842418.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/c15\/18c\/4e2\/c1518c4e2193d32875355dedfb842418.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0412\u044b\u0447\u0435\u0440\u043a\u043d\u0443\u043b\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438 \u0432\u0441\u0435\u043c \u044d\u0442\u043e\u043c \u0437\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d, \u0442.\u043a. \u0434\u043b\u044f \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u0432 (\u0433\u0440\u0443\u043f\u043f), \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c, \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044f \u043d\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f, \u0430 \u0442\u0430\u043c, \u0433\u0434\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u043c\u0435\u043d\u044f\u043b\u0441\u044f (\u0438 \u043d\u0430\u0434\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044f), \u0435\u0433\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u043e\u0442\u0440\u0430\u0436\u0430\u043b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0422\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u043a\u043e\u043f\u0438\u044e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0435\u0433\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u044b.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0438 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0438\u0434\u0435\u044f &#8212; \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0434\u043e\u0445\u043e\u0434\u0438\u043c \u0434\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u043d\u0435\u0440\u0430\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044e, \u0442\u043e \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0433\u0440\u0443\u043f\u043f\u044b, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0442\u043d \u0430\u0442\u0440\u0438\u0431\u0443\u0442. \u0418\u043b\u0438, \u0447\u0442\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, &#8212; \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u043f\u043e\u0434 \u043d\u043e\u043c\u0435\u0440\u043e\u043c N \u043c\u044b \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u043d\u0435 \u043c\u0435\u043d\u044c\u0448\u0435 N.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/6f7\/5c8\/469\/6f75c8469d7884d3f4bc419afea9eaf2.gif\" alt=\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 3 GS - abc, ab, a\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/6f7\/5c8\/469\/6f75c8469d7884d3f4bc419afea9eaf2.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/6f7\/5c8\/469\/6f75c8469d7884d3f4bc419afea9eaf2.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 3 GS &#8212; abc, ab, a<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/ec1\/50d\/433\/ec150d43360aa5aba739dceb6ca0ec90.gif\" alt=\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 2 GS - abc, a\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/ec1\/50d\/433\/ec150d43360aa5aba739dceb6ca0ec90.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/ec1\/50d\/433\/ec150d43360aa5aba739dceb6ca0ec90.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 2 GS &#8212; abc, a<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 (\u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u044f) \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c, \u043a\u0430\u043a \u0438 \u0440\u0430\u043d\u044c\u0448\u0435, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0438 \u043d\u0435\u0440\u0430\u0432\u043d\u044b\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u044b \u0440\u0430\u0437\u043d\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432. \u0420\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u043e \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u0438 \u0432\u043d\u0443\u0442\u0440\u044c \u043b\u0435\u0437\u0442\u044c \u043d\u0430\u043c \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043f\u0440\u043e\u0449\u0435: \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 GS \u043c\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0441\u0432\u043e\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0435\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L3605 *\/static void ExecInitAgg(Agg *node, EState *estate, int eflags){   \/* for each grouping set *\/   for (int k = 0; k &lt; phasedata-&gt;numsets; k++)   {      int length = phasedata-&gt;gset_lengths[k];      \/* nothing to do for empty grouping set *\/      if (length == 0)         continue;      \/* if we already had one of this length, it'll do *\/      if (phasedata-&gt;eqfunctions[length - 1] != NULL)         continue;      phasedata-&gt;eqfunctions[length - 1] =         execTuplesMatchPrepare(scanDesc, length,                                aggnode-&gt;grpColIdx,                                aggnode-&gt;grpOperators,                                aggnode-&gt;grpCollations,                                (PlanState *) aggstate);   }}\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execGrouping.c#L58 *\/ExprState *execTuplesMatchPrepare(TupleDesc desc, int numCols,                                  const AttrNumber *keyColIdx,                                  const Oid *eqOperators,                                  const Oid *collations,                                  PlanState *parent){   Oid          *eqFunctions;   int           i;   ExprState    *expr;   if (numCols == 0)      return NULL;   eqFunctions = (Oid *) palloc(numCols * sizeof(Oid));   \/* lookup equality functions *\/   for (i = 0; i &lt; numCols; i++)      eqFunctions[i] = get_opcode(eqOperators[i]);   \/* build actual expression *\/   expr = ExecBuildGroupingEqual(desc, desc, NULL, NULL,                                 numCols, keyColIdx, eqFunctions, collations,                                 parent);   return expr;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0412\u0441\u0435, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, &#8212; \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b ROLLUP, \u043d\u043e \u044d\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430, \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043e \u043d\u0435\u043c \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043c. \u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435, \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0430\u043c\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0438\u0436\u0435 \u0438 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u0437\u0430\u0434\u0430\u0447\u0435\u0439.<\/p>\n<pre><code class=\"sql\">SELECT a, b, c FROM tbl GROUP BY GROUPING SETS (   (c, b, a),   (b, a),   (a));        QUERY PLAN------------------------------- GroupAggregate   Group Key: a, b, c   Group Key: a, b   Group Key: a   -&gt;  Sort         Sort Key: a, b, c         -&gt;  Seq Scan on tbl(7 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0432\u0441\u0435 \u0442\u0430 \u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>agg_retrieve_direct<\/code>, \u0438 \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u043d\u0443\u0442\u0440\u044c \u0435\u0449\u0435 \u0440\u0430\u0437, \u0442\u043e \u0432 \u0442\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u043c\u044b \u043d\u0438\u0447\u0435\u0433\u043e \u043e GROUPING SETS \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043c &#8212; \u043d\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0438\u0445 \u0433\u0440\u0430\u043d\u0438\u0446, \u043d\u0438 \u0434\u0430\u0436\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u0432 (\u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e).<\/p>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f &#8212; \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u043d\u0430\u044f, \u0442.\u0435. \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u043e 1 \u043a\u043e\u0440\u0442\u0435\u0436\u0443 \u0437\u0430 \u0440\u0430\u0437, \u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0434\u043e\u0445\u043e\u0434\u0438\u043c \u0434\u043e \u043d\u0435\u0440\u0430\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430, \u0442\u043e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u0440\u0443\u043f\u043f. \u041d\u0430\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f, \u043a\u0440\u043e\u043c\u0435 \u043a\u0430\u043a \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c, \u043d\u0430 \u043a\u0430\u043a\u043e\u043c GS \u043c\u044b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c, \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0435, \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u043d\u0430\u043c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0433\u0440\u0443\u043f\u043f\u0443.<\/p>\n<p>\u0410 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0438\u043b\u044c\u043d\u043e \u043d\u0435 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e, \u0441\u0430\u043c\u043e\u0433\u043e \u0447\u0430\u0441\u0442\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f (\u0431\u0435\u0437 <code>GROUPING SETS<\/code>), \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u044b \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043c \u043e\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e GS \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u043c\u0443, \u0442.\u0435. \u0432 \u0441\u0430\u043c\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c\u0443\u044e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0443 (\u0435\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0430\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d &#8212; \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438), \u0430 \u0437\u0430\u0442\u0435\u043c \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a GS \u043c\u0435\u043d\u044c\u0448\u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435 (\u0441 3 GS), \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u044b\u0432\u043e\u0434:<\/p>\n<pre><code class=\"sql\">SELECT a, b, c FROM tbl GROUP BY GROUPING SETS((a, b, c), (a, b), (a)); a | b | c ---+---+--- 1 | 1 | 1 1 | 1 | 2 1 | 1 |   1 | 2 | 1 1 | 2 |   1 |   |   2 | 2 | 1 2 | 2 |   2 |   |  (9 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0448\u0435 (\u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 3-\u0445 GS), \u0442\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u0435, \u0447\u0442\u043e \u0432\u044b\u0432\u043e\u0434 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 \u0442\u043e\u0439 \u0436\u0435 \u0441\u0430\u043c\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 &#8212; \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u043c \u043d\u0435\u0440\u0430\u0432\u043d\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0432 \u0443\u0431\u044b\u0432\u0430\u044e\u0449\u0435\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443 GS.<\/p>\n<blockquote>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u043f\u043e\u0447\u0435\u043c\u0443 \u0433\u0440\u0443\u043f\u043f\u044b \u0432 \u0432\u044b\u0432\u043e\u0434\u0435 \u0438\u0434\u0443\u0442 \u043f\u0438\u043b\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/p>\n<\/blockquote>\n<p>\u041a\u043e\u0434 (\u0446\u0438\u043a\u043b) \u0440\u0430\u043d\u0435\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441\u043e \u0432\u0445\u043e\u0434\u043e\u043c \u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0443, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0435\u0442 &#8212; \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0433\u0440\u0443\u043f\u043f\u044b. \u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043b\u0435\u0436\u0438\u0442 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0446\u0438\u043a\u043b\u0430, \u0438 \u0432\u043e\u043e\u0431\u0449\u0435, \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438:<\/p>\n<ol>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b (\u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438\u0437 \u0432\u0445\u043e\u0434\u0430)<\/p>\n<\/li>\n<li>\n<p>\u0424\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u044b\u0445 GS (\u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f)<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0434\u0435\u0441\u044c \u0443 \u043d\u0430\u0441 <code>if<\/code>\/<code>else<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u0435. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c GS \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0438\u0445.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2422 *\/static TupleTableSlot *agg_retrieve_direct(AggState *aggstate){   if (node-&gt;aggstrategy != AGG_PLAIN &amp;&amp;       aggstate-&gt;projected_set != -1 &amp;&amp;       aggstate-&gt;projected_set &lt; (numGroupingSets - 1) &amp;&amp;       \/* \u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0441 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u0435\u043b\u0435\u043c *\/       !ExecQualAndReset(aggstate-&gt;phase-&gt;eqfunctions[nextSetSize - 1], tmpcontext))   {       \/* \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c\u0443 GS *\/       aggstate-&gt;projected_set += 1;   }   else   {       \/* \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0438\u0437 \u0432\u0445\u043e\u0434\u0430 *\/       aggstate-&gt;projected_set = 0;       \/* ... \u0442\u0443\u0442 \u043a\u043e\u0434 ... *\/   }   \/* \u0424\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b *\/   select_current_set(aggstate, aggstate-&gt;projected_set, false);   finalize_aggregates(aggstate, peragg, pergroups);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c <code>ROLLUP<\/code> \u0437\u0430 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0445\u043e\u0434 \u0432 \u043f\u043e\u0442\u043e\u043a\u0435. \u0418 \u0438\u043c\u0435\u043d\u043d\u043e <code>ROLLUP<\/code>! \u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u044b\u0435 \u0440\u0430\u0437\u043d\u044b\u0435 GS. \u041d\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0433\u043e \u043e\u0442 \u043d\u0430\u0441 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 &#8212; \u043d\u0435\u043b\u044c\u0437\u044f \u0437\u0430 \u0440\u0430\u0437 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u0440\u0430\u0437\u043d\u044b\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u044d\u0442\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u044f\u0432\u043d\u0443\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 <code>c<\/code>.<\/p>\n<pre><code class=\"sql\">SELECT a, b, c FROM tbl GROUP BY GROUPING SETS (   (b, a),   (a),   (c));          QUERY PLAN-------------------------------- GroupAggregate   Group Key: a, b   Group Key: a   Sort Key: c     Group Key: c   -&gt;  Sort         Sort Key: a, b         -&gt;  Seq Scan on tbl (8 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u043c\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u0445\u0438\u0442\u0440\u0435\u0435, \u043d\u0435\u0436\u0435\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0432 <code>agg_retrieve_direct<\/code>. \u041c\u044b \u0438\u0434\u0435\u043c \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u0435, \u043a\u0430\u043a \u201c\u0444\u0430\u0437\u0430\u201d (phase). \u0412\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0444\u0430\u0437, \u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0444\u0430\u0437\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c <em>\u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e<\/em>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0444\u0430\u0437\u044b \u0431\u0443\u0434\u0435\u0442 ROLLUP.<\/p>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0444\u0430\u0437\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 <code>AggStatePerPhase<\/code>, \u0438 \u0432 \u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0444\u0430\u0437\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0444\u0430\u0437\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u0435 \u043d\u0430\u0431\u043e\u0440\u044b GS &#8212; \u0445\u0440\u0430\u043d\u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043f\u043e \u043a\u0430\u043a\u0438\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c \u0438\u0434\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430. \u0422\u0430\u043a\u0436\u0435 \u0440\u0430\u043d\u0435\u0435 \u043c\u044b \u0443\u0432\u0438\u0434\u0435\u043b\u0438, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 &#8212; \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0437\u0434\u0435\u0441\u044c.<\/p>\n<details class=\"spoiler\">\n<summary>AggStatePerPhaseData<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/executor\/nodeAgg.h#L280 *\/typedef struct AggStatePerPhaseData{   AggStrategy aggstrategy;    \/* strategy for this phase *\/    int            numsets;           \/* number of grouping sets (or 0) *\/    int           *gset_lengths;    \/* lengths of grouping sets *\/    Bitmapset **grouped_cols;    \/* column groupings for rollup *\/    ExprState **eqfunctions;    \/* expression returning equality, indexed by                                       * nr of cols to compare *\/    Agg           *aggnode;        \/* Agg node for phase data *\/    Sort          *sortnode;        \/* Sort node for input ordering for phase *\/    ExprState  *evaltrans;        \/* evaluation of transition functions  *\/    \/*----------     * Cached variants of the compiled expression.     * first subscript: 0: outerops; 1: TTSOpsMinimalTuple     * second subscript: 0: no NULL check; 1: with NULL check     *----------     *\/    ExprState  *evaltrans_cache[2][2];} AggStatePerPhaseData;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043c\u0435\u0436\u0434\u0443 \u0444\u0430\u0437\u0430\u043c\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u0432\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438: <code>sort_in<\/code> \u0438 <code>sort_out<\/code>. \u0415\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0444\u0430\u0437\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0430\u0437\u0435, \u0442\u043e \u043e\u043d\u0430 \u043a\u043b\u0430\u0434\u0435\u0442 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0432 <code>sort_out<\/code>. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0430\u0437\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430, \u0438 \u043e\u043d\u0438 (\u043a\u043e\u0440\u0442\u0435\u0436\u0438) \u043a\u043b\u0430\u0434\u0443\u0442\u0441\u044f \u0432 <code>sort_in<\/code>, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0447\u0438\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0444\u0430\u0437\u0430.<\/p>\n<p>\u041b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c \u044d\u0442\u0443 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u044d\u0442\u0430 \u0441\u0445\u0435\u043c\u0430:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d50\/769\/d37\/d50769d375cd0c50c261182f85f4ae45.png\" alt=\"\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0444\u0430\u0437\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/d50\/769\/d37\/d50769d375cd0c50c261182f85f4ae45.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d50\/769\/d37\/d50769d375cd0c50c261182f85f4ae45.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0444\u0430\u0437<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0442\u0430\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430:<\/p>\n<pre><code class=\"sql\">SELECT a, b, c, d, e, i, j, k FROM tbl   GROUP BY GROUPING SETS(      ROLLUP(a, b, c), ROLLUP(d, e), ROLLUP(i, j, k)   );         QUERY PLAN   ---------------------------- GroupAggregate   Group Key: d, e   Group Key: d   Group Key: ()   Group Key: ()   Group Key: ()   Sort Key: a, b, c     Group Key: a, b, c     Group Key: a, b     Group Key: a   Sort Key: i, j, k     Group Key: i, j, k     Group Key: i, j     Group Key: i   -&gt;  Sort         Sort Key: d, e         -&gt;  Seq Scan on tt(17 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<details class=\"spoiler\">\n<summary>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043f\u043b\u043e\u0441\u043a\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u044f\u0432\u043d\u044b\u0445 <code>ROLLUP<\/code>, \u0432\u043c\u0435\u0441\u0442\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 <code>GROUPING SETS<\/code>, \u0438 \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 ROLLUP \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u043b\u043e\u0441\u043a\u0438\u0445 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043e\u043a. \u041f\u0440\u0438\u0447\u0435\u043c \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c &#8212; \u0432\u0441\u0435 \u043f\u0443\u0441\u0442\u044b\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0444\u0430\u0437\u0435.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 &#8212; \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u043d\u043e\u0441\u0438\u0442 \u0432\u0441\u0435 \u043f\u043b\u043e\u0441\u043a\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0443\u0437\u0435\u043b, \u0433\u0434\u0435 \u0431\u044b \u043e\u043d\u0438 \u043d\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0438\u0441\u044c. \u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e &#8212; \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u0447\u0438\u043d. \u041c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f &#8212; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u043b\u044f \u043d\u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0430 \u0437\u0430\u0442\u0435\u043c \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c (\u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c trans\/agg \u0432 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u0445).<\/p>\n<p>\u041d\u043e \u044f \u0432\u0441\u0435 \u0436\u0435 \u0441\u043a\u043b\u043e\u043d\u044f\u044e\u0441\u044c \u043a \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0443 \u0434\u0435\u0442\u0430\u043b\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 <code>ROLLUP<\/code>, \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043b\u043e\u0441\u043a\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043e\u043a, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u043d\u0438\u043c. \u0417\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043b\u043e\u0441\u043a\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u044d\u0442\u0438\u0445 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043e\u043a \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 <code>expand_grouping_sets<\/code>, \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0435\u0433\u043e \u044d\u0442\u0430\u043f\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 GS \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/parser\/parse_agg.c#L2007 *\/List *expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit){   \/* \u043f\u043b\u043e\u0441\u043a\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 GS *\/   List *result;   \/* ... *\/    if (!groupDistinct || list_length(result) &lt; 2)        list_sort(result, cmp_list_len_asc);   return result;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435, \u0442\u043e \u043f\u043e\u0442\u0435\u0440\u044f\u0435\u043c \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438, \u0438 \u043e\u043d\u0438 \u0441\u0442\u0430\u043d\u0443\u0442 \u0440\u0430\u0432\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u043c\u0438. \u041a\u043e\u0433\u0434\u0430 \u0436\u0435 \u043d\u0430\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <code>ROLLUP<\/code> \u0438\u0437 \u043f\u043b\u043e\u0441\u043a\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 GS, \u044d\u0442\u0438 \u043f\u0443\u0441\u0442\u044b\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0430\u0434\u043e \u043a\u0443\u0434\u0430-\u0442\u043e \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c &#8212; \u043a\u043b\u0430\u0434\u0435\u043c \u0438\u0445 \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 <code>ROLLUP<\/code>. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 <code>extract_rollup_sets<\/code>:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/optimizer\/plan\/planner.c#L2924 *\/static List *extract_rollup_sets(List *groupingSets){    \/*     * Start by stripping out empty sets.  The algorithm doesn't require this,     * but the planner currently needs all empty sets to be returned in the     * first list, so we strip them here and add them back after.     *\/    while (lc1 &amp;&amp; lfirst(lc1) == NIL)    {        ++num_empty;        lc1 = lnext(groupingSets, lc1);    }    \/* ... *\/       \/* push any empty sets back on the first list. *\/    while (num_empty-- &gt; 0)        results[1] = lcons(NIL, results[1]);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0443 \u0430 \u0435\u0441\u043b\u0438 \u043c\u044b \u0435\u0449\u0435 \u043f\u043e\u043a\u043e\u043f\u0430\u0435\u043c\u0441\u044f, \u0442\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0434\u043e\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438.<\/p>\n<blockquote>\n<p>\u041f\u043e\u0447\u0442\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0432\u044b\u0448\u0435 \u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u043b <code>enable_hashagg<\/code>, \u0442.\u043a. \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0447\u0435\u043d\u044c \u0447\u0430\u0441\u0442\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0435\u0435, \u043d\u043e \u0434\u0430\u0436\u0435 \u0442\u0430\u043a, \u0435\u0441\u043b\u0438 \u0431\u044b\u043b\u0430 \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430, \u0442\u043e \u043f\u043e\u044f\u0432\u043b\u044f\u043b\u0441\u044f <code>Group Key<\/code> &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0431\u0435\u0437 \u044d\u0442\u043e\u0439 \u0441\u0430\u043c\u043e\u0439 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438.<\/p>\n<\/blockquote>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0434\u0435\u0442\u0430\u043b\u044c \u043f\u0430\u0437\u043b\u0430 &#8212; \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0444\u0430\u0437\u0430\u043c\u0438. \u0422\u0443\u0442 \u043c\u044b \u0435\u0449\u0435 \u0440\u0430\u0437 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e &#8212; <code>fetch_input_tuple<\/code>.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L549 *\/static TupleTableSlot *fetch_input_tuple(AggState *aggstate){    TupleTableSlot *slot;    if (aggstate-&gt;sort_in)    {        if (!tuplesort_gettupleslot(aggstate-&gt;sort_in, true, false,                                    aggstate-&gt;sort_slot, NULL))            return NULL;        slot = aggstate-&gt;sort_slot;    }    else        slot = ExecProcNode(outerPlanState(aggstate));    if (!TupIsNull(slot) &amp;&amp; aggstate-&gt;sort_out)        tuplesort_puttupleslot(aggstate-&gt;sort_out, slot);    return slot;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0432\u044b\u0437\u043e\u0432 <code>ExecProcNode<\/code> &#8212; \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u201c\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u201d \u043f\u043e\u0434\u0443\u0437\u0435\u043b \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043a\u043e\u0440\u0442\u0435\u0436 \u0438\u0437 \u043d\u0435\u0433\u043e, \u0430 \u0432\u043e\u0442 \u0437\u0430 \u044d\u0442\u0438 \u0441\u0430\u043c\u044b\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043a\u043e\u0434 \u0432\u043e\u043a\u0440\u0443\u0433.<\/p>\n<blockquote>\n<p>\u041e\u043f\u044f\u0442\u044c \u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0441\u0435\u0431\u0435 \u0434\u043e\u043f\u0443\u0449\u0435\u043d\u0438\u0435 &#8212; \u043d\u0430\u0437\u0432\u0430\u043b \u044d\u0442\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b\/\u043f\u043e\u043b\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u044f\u043c\u0438. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044d\u0442\u0438 \u201c\u043e\u0447\u0435\u0440\u0435\u0434\u0438\u201d \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f (\u043d\u0438\u0436\u0435\u043b\u0435\u0436\u0430\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 <code>Tuplesortstate<\/code>. \u041e\u043d \u043d\u0430\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e, \u0442.\u043a. \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0434\u0430\u0436\u0435 \u0442\u043e, \u0447\u0442\u043e \u0443\u0436\u0435 \u0441\u0431\u0440\u043e\u0448\u0435\u043d\u043e \u043d\u0430 \u0434\u0438\u0441\u043a.<\/p>\n<\/blockquote>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0444\u0430\u0437\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0445\u043e\u0434, \u0442\u043e \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0444\u0430\u0437\u0443. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>initialize_phase<\/code>, \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0435\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0441\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L479 *\/static voidinitialize_phase(AggState *aggstate, int newphase){   \/* \u0412\u0445\u043e\u0434 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0444\u0430\u0437\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0441\u044f - \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u043c\u0435\u0441\u0442\u043e *\/   if (aggstate-&gt;sort_in)   {      tuplesort_end(aggstate-&gt;sort_in);      aggstate-&gt;sort_in = NULL;   }   \/* \u041c\u0435\u043d\u044f\u0435\u043c \u043c\u0435\u0441\u0442\u0430\u043c\u0438 sort_in \u0438 sort_out \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u044f\u0435\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 *\/   aggstate-&gt;sort_in = aggstate-&gt;sort_out;   aggstate-&gt;sort_out = NULL;   tuplesort_performsort(aggstate-&gt;sort_in);   \/* \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0430\u0437\u044b *\/   if (newphase &gt; 0 &amp;&amp; newphase &lt; aggstate-&gt;numphases - 1)   {      Sort       *sortnode = aggstate-&gt;phases[newphase + 1].sortnode;      PlanState  *outerNode = outerPlanState(aggstate);      TupleDesc    tupDesc = ExecGetResultType(outerNode);      aggstate-&gt;sort_out = tuplesort_begin_heap(tupDesc,                                                sortnode-&gt;numCols,                                                sortnode-&gt;sortColIdx,                                                sortnode-&gt;sortOperators,                                                sortnode-&gt;collations,                                                sortnode-&gt;nullsFirst,                                                work_mem,                                                NULL, TUPLESORT_NONE);   }   aggstate-&gt;current_phase = newphase;   aggstate-&gt;phase = &amp;aggstate-&gt;phases[newphase];}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h4>MixedAggregate<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e GROUPING SETS \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u0418\u041b\u0418 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c, \u043d\u043e \u043f\u043e\u043a\u0430 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0430\u043a \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432\u043c\u0435\u0441\u0442\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u044b\u043b\u0430 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043d\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f MixedAggregate. \u0415\u0435 \u0438\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u0443\u0437\u043b\u0435 \u043f\u043b\u0430\u043d\u0430 \u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443, \u043f\u0440\u0438\u0447\u0435\u043c \u0434\u043b\u044f <em>\u043a\u0430\u0436\u0434\u043e\u0433\u043e GS \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/em> \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0435\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u043b\u0430\u043d \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0438\u0437 \u0441\u0435\u0431\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442.<\/p>\n<pre><code class=\"sql\">SELECT a, b from tbl3 group by cube(a, b);                   QUERY PLAN---------------------------------------------------- MixedAggregate   Hash Key: b   Group Key: a, b   Group Key: a   Group Key: ()   -&gt;  Index Only Scan using tbl3_a_b_idx on tbl3(6 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0443\u0432\u0438\u0434\u0435\u043b, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0438\u043d\u0434\u0435\u043a\u0441 \u0441 \u043d\u0443\u0436\u043d\u043e\u0439 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439, \u043d\u043e \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e GS \u043e\u043d \u0440\u0435\u0448\u0438\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 \u201c\u043a\u0430\u043a \u0441\u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u0435\u043c \u0432\u043c\u0435\u0441\u0442\u0435\u201d \u043e\u0442\u0432\u0435\u0442\u0438\u043c \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439, \u0442\u043e\u0436\u0435 \u0432\u0430\u0436\u043d\u044b\u0439 &#8212; \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u0444\u0430\u0437? \u0412 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 (\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u044f \u0434\u0430\u043b \u0438 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u0432 \u043a\u043e\u0434\u0435) \u0441\u043a\u0430\u0437\u0430\u043d\u043e: \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0430\u0437\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u0441\u0435 GS, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0437\u0430 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0445\u043e\u0434. \u041d\u043e \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0435 GS \u0437\u0430 \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0445\u043e\u0434! \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043c\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0444\u0430\u0437\u0443.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/433\/d61\/a30\/433d61a302d3d229487535ce24697c49.png\" alt=\"\u0424\u0430\u0437\u0430 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0434\u043d\u0430\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/433\/d61\/a30\/433d61a302d3d229487535ce24697c49.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/433\/d61\/a30\/433d61a302d3d229487535ce24697c49.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0424\u0430\u0437\u0430 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0434\u043d\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u0435\u0440\u0435\u0444\u0440\u0430\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u0442\u0430\u043a: \u043a\u0443\u0434\u0430 \u043c\u044b \u0432\u0441\u0442\u0430\u0432\u0438\u043c \u044d\u0442\u0443 \u0444\u0430\u0437\u0443 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438? \u0412 \u043d\u0430\u0447\u0430\u043b\u043e &#8212; \u043d\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430 \u0432\u0445\u043e\u0434 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 (\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e, \u0438\u0437 \u0438\u043d\u0434\u0435\u043a\u0441\u0430) \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0435\u0449\u0435 \u0440\u0430\u0437. \u041a\u0443\u0434\u0430-\u0442\u043e \u0432 \u201c\u043c\u0435\u0436\u0434\u0443 \u0444\u0430\u0437\u0430\u043c\u0438\u201d \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 &#8212; \u0442\u043e\u0436\u0435 \u043d\u0435 \u043b\u0443\u0447\u0448\u0430\u044f \u0437\u0430\u0442\u0435\u044f, \u0432\u0435\u0434\u044c \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443, \u0430 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043e\u043d\u0430 \u043d\u0435 \u043d\u0443\u0436\u043d\u0430.<\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0445\u043e\u0434 \u043a\u043e\u043d\u0435\u043c. \u0412\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0434\u0432\u0430 \u044d\u0442\u0430\u043f\u0430 &#8212; \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u041c\u044b \u0441\u043d\u043e\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u044d\u0442\u043e. \u0412 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c \u0432\u0441\u0435 \u0444\u0430\u0437\u044b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438, \u043a\u0430\u043a \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u0430 \u0444\u0430\u0437\u0443 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439. \u041d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c <em>\u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u0444\u0430\u0437\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443<\/em> (\u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c, \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c), \u0430 \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u0432\u0441\u0435 \u0444\u0430\u0437\u044b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438, \u0442\u043e \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e. \u0410 \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0443\u0436\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u0442\u043e \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/2ba\/ac9\/e9e\/2baac9e9e145e1cdd4ebfb1bdf511d06.png\" alt=\"\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 MixedAggregate\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/2ba\/ac9\/e9e\/2baac9e9e145e1cdd4ebfb1bdf511d06.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/2ba\/ac9\/e9e\/2baac9e9e145e1cdd4ebfb1bdf511d06.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 MixedAggregate<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/052\/d99\/12d\/052d9912d499eca3298ef76ad2c9fd13.gif\" alt=\"\u0420\u0430\u0431\u043e\u0442\u0430 MixedAggregate\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/052\/d99\/12d\/052d9912d499eca3298ef76ad2c9fd13.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/\/post_images\/052\/d99\/12d\/052d9912d499eca3298ef76ad2c9fd13.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0420\u0430\u0431\u043e\u0442\u0430 MixedAggregate<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u201c\u0445\u0430\u043a\u0430\u201d \u0441\u0434\u0435\u043b\u0430\u043d\u043e 2 \u0432\u0435\u0449\u0438. \u041f\u0435\u0440\u0432\u043e\u0435 &#8212; \u0432 \u043a\u043e\u0434 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432\u043a\u0440\u0430\u043f\u043b\u0435\u043d\u0438\u0435 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u0443\u0436\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043d\u0430\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>lookup_hash_entries<\/code>:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2533 *\/static TupleTableSlot *agg_retrieve_direct(AggState *aggstate){   outerslot = fetch_input_tuple(aggstate);   initialize_aggregates(aggstate);   for (;;)   {        \/*       * During phase 1 only of a mixed agg, we need to update       * hashtables as well in advance_aggregates.       *\/      if (aggstate-&gt;aggstrategy == AGG_MIXED &amp;&amp;          aggstate-&gt;current_phase == 1)      {         lookup_hash_entries(aggstate);      }        \/* ... *\/   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0434\u0435\u043b\u0430\u0435\u0442, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u043f\u043e\u0447\u0435\u043c\u0443 <code>current_phase == 1<\/code>? \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0444\u0430\u0437\u0430 0 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0430 \u043f\u043e\u0434 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0434\u0430\u0436\u0435 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u0444\u0430\u0437 \u0438\u043d\u0434\u0435\u043a\u0441 0 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0434\u0435\u043b\u0435\u043d \u043f\u043e\u0434 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0436\u0435 \u043c\u044b \u0434\u043e\u0439\u0434\u0435\u043c \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0444\u0430\u0437\u044b, \u0442\u043e \u043e\u0442 \u043d\u0435\u0435 (\u043f\u043e\u0434 \u043d\u043e\u043c\u0435\u0440\u043e\u043c N) \u043c\u044b \u043f\u0435\u0440\u0435\u0441\u043a\u043e\u0447\u0438\u043c \u043d\u0430 \u0444\u0430\u0437\u0443 0:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2361 *\/static TupleTableSlot *agg_retrieve_direct(AggState *aggstate){   \/*    * Check if input is complete and there are no more groups to project    * in this phase; move to next phase or mark as done.    *\/   if (aggstate-&gt;input_done == true &amp;&amp;       aggstate-&gt;projected_set &gt;= (numGroupingSets - 1))   {      if (aggstate-&gt;current_phase &lt; aggstate-&gt;numphases - 1)      {         \/* \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0444\u0430\u0437\u0443 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 *\/      }      else if (aggstate-&gt;aggstrategy == AGG_MIXED)      {         \/*          * Mixed mode; we've output all the grouped stuff and have          * full hashtables, so switch to outputting those.          *\/         initialize_phase(aggstate, 0);         \/* ... *\/         return agg_retrieve_hash_table(aggstate);      }      else      {         aggstate-&gt;agg_done = true;         break;      }   }   \/* ... *\/}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0443\u0437\u043b\u0430 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0430 \u043d\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 <code>ExecAgg<\/code> \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043d\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e, \u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0444\u0430\u0437\u044b:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2254 *\/static TupleTableSlot *ExecAgg(PlanState *pstate){    AggState       *node = castNode(AggState, pstate);    TupleTableSlot *result = NULL;    if (!node-&gt;agg_done)    {      \/* \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0444\u0430\u0437\u044b, \u0430 \u043d\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e *\/        switch (node-&gt;phase-&gt;aggstrategy)        {            case AGG_HASHED:                if (!node-&gt;table_filled)                    agg_fill_hash_table(node);                \/* FALLTHROUGH *\/            case AGG_MIXED:                result = agg_retrieve_hash_table(node);                break;            case AGG_PLAIN:            case AGG_SORTED:                result = agg_retrieve_direct(node);                break;        }        if (!TupIsNull(result))            return result;    }    return NULL;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u041e\u0441\u0442\u0430\u0432\u0448\u0435\u0435\u0441\u044f \u0437\u0430 \u043a\u0430\u0434\u0440\u043e\u043c<\/h3>\n<p>\u041c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 \u043e\u0431\u0449\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0438 \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438, \u043d\u043e \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043f\u0430\u0440\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0432\u043e\u0448\u043b\u0438, \u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b.<\/p>\n<h4>\u0427\u0430\u0441\u0442\u0438\u0447\u043d\u0430\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044f<\/h4>\n<p>\u041d\u0430\u0440\u044f\u0434\u0443 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 (<code>transfn<\/code>) \u0443 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f (<code>combinefn<\/code>). \u0415\u0435 \u0438\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430 \u0432\u0445\u043e\u0434 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0434\u0430\u0442\u044c \u043d\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430, \u0430 \u0434\u0440\u0443\u0433\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043a\u0430\u043a \u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0437\u0430 \u0440\u0430\u0437 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0434\u043d\u043e\u0433\u043e. \u0427\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u044b \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043f\u0440\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438, \u043a\u0430\u043a \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"sql\">SELECT a, sum(b) FROM pagg_tab GROUP BY a;                          QUERY PLAN                    -------------------------------------------------------Finalize HashAggregate   Group Key: pagg_tab.a   -&gt;  Append         -&gt;  Partial HashAggregate               Group Key: pagg_tab.a               -&gt;  Seq Scan on pagg_tab_p1 pagg_tab         -&gt;  Partial HashAggregate               Group Key: pagg_tab_1.a               -&gt;  Seq Scan on pagg_tab_p2 pagg_tab_1         -&gt;  Partial HashAggregate               Group Key: pagg_tab_2.a               -&gt;  Seq Scan on pagg_tab_p3 pagg_tab_2<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0445 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u0432 \u043f\u043b\u0430\u043d\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0443\u0437\u043b\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430\u043c\u0438 <code>Partial<\/code> \u0438 <code>Finalize<\/code>. \u0418\u0445 \u0438\u0434\u0435\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c: <code>Partial<\/code> \u0443\u0437\u043b\u044b <em>\u043d\u0435<\/em> \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0442 \u0430\u0433\u0440\u0435\u0433\u0430\u0442 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442 \u0432\u044b\u0448\u0435 \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0430 <code>Finalize<\/code> \u0443\u0437\u0435\u043b \u0443\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f (\u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430) \u0438 \u0441\u0430\u043c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440. \u0421\u0430\u043c\u043e\u0435 \u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435, \u0447\u0442\u043e \u0432\u0441\u044f \u044d\u0442\u0430 \u043c\u0430\u0433\u0438\u044f \u0442\u0432\u043e\u0440\u0438\u0442\u0441\u044f <em>\u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/em>. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u043e\u0432 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0442\u0430\u043a\u0438\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043d\u0435\u0442. \u041f\u043e\u0447\u0435\u043c\u0443?<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043a\u043e\u0434, \u0442\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043a\u043e\u0434 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043e \u0442\u0438\u043f\u0430\u0445 \u0438\u043b\u0438 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u0430\u043a: \u0447\u0438\u0442\u0430\u0435\u0442 (\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442) \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0438\u0437 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439 <code>AggStatePerGroup FUNCTION(AggStatePerGroup, Datum args...)<\/code>. <code>Datum<\/code> &#8212; \u044d\u0442\u043e \u0441\u0430\u043c\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a <code>void *<\/code>. \u0422\u043e \u0435\u0441\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043a\u043e\u0434\u0430 \u043e\u043d \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u0435\u043d, \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043a\u043e\u0434 \u0437\u043d\u0430\u0435\u0442, \u043a\u0430\u043a \u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043c \u0431\u0435\u0437 \u0440\u0430\u0437\u043d\u0438\u0446\u044b, \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 &#8212; \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0438\u0437 \u043a\u043e\u0440\u0442\u0435\u0436\u0430. \u0422\u043e \u0435\u0441\u0442\u044c \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0442\u043e \u0434\u043b\u044f \u043d\u0430\u0441 (\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438) \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u0441\u044f. \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u0437\u043b\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>ExecInitAgg<\/code>, \u0438 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043e\u0431\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438.<\/p>\n<p>\u0414\u043b\u044f <code>Finalize<\/code> \u043c\u044b \u043f\u043e\u0434\u043c\u0435\u043d\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L3948 *\/AggState *ExecInitAgg(Agg *node, EState *estate, int eflags){   ListCell *lc;      foreach(l, aggstate-&gt;aggs)   {      Oid transfn_oid;      \/*       * If this aggregation is performing state combines, then instead       * of using the transition function, we'll use the combine       * function.       *\/      if (DO_AGGSPLIT_COMBINE(aggstate-&gt;aggsplit))      {         transfn_oid = aggform-&gt;aggcombinefn;         \/* If not set then the planner messed up *\/         if (!OidIsValid(transfn_oid))            elog(ERROR, \"combinefn not set for aggregate function\");      }      else         transfn_oid = aggform-&gt;aggtransfn;      \/* ... *\/      \/* aggcombinefn always has two arguments of aggtranstype *\/      build_pertrans_for_aggref(pertrans, aggstate, estate,                                aggref, transfn_oid, aggtranstype,                                serialfn_oid, deserialfn_oid,                                initValue, initValueIsNull,                                combineFnInputTypes, 2);   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f <code>Partial<\/code> \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0435\u0433\u043e.<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L3806 *\/AggState *ExecInitAgg(Agg *node, EState *estate, int eflags){   ListCell *lc;      foreach(l, aggstate-&gt;aggs)   {      AggStatePerAgg peragg;        \/* Final function only required if we're finalizing the aggregates *\/        if (DO_AGGSPLIT_SKIPFINAL(aggstate-&gt;aggsplit))            peragg-&gt;finalfn_oid = finalfn_oid = InvalidOid;        else            peragg-&gt;finalfn_oid = finalfn_oid = aggform-&gt;aggfinalfn;        \/* \u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 *\/        if (OidIsValid(finalfn_oid))        {            build_aggregate_finalfn_expr(aggTransFnInputTypes,                                      peragg-&gt;numFinalArgs,                                      aggtranstype,                                      aggref-&gt;aggtype,                                      aggref-&gt;inputcollid,                                      finalfn_oid,                                      &amp;finalfnexpr);            fmgr_info(finalfn_oid, &amp;peragg-&gt;finalfn);            fmgr_info_set_expr((Node *) finalfnexpr, &amp;peragg-&gt;finalfn);        }   }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<details class=\"spoiler\">\n<summary>\u041a\u0430\u043a \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0442 Partial, Finalize \u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0443\u0437\u043b\u044b \u0432 \u043a\u043e\u0434\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041a\u0430\u043a \u0443\u0436\u0435 \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0442\u044c \u0442\u0438\u043f \u0443\u0437\u043b\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435 <code>aggstate-&gt;aggsplit<\/code>. \u042d\u0442\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0441 \u0431\u0438\u0442\u043e\u0432\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/nodes\/nodes.h#L374 *\/\/* Primitive options supported by nodeAgg.c: *\/#define AGGSPLITOP_COMBINE        0x01    \/* substitute combinefn for transfn *\/#define AGGSPLITOP_SKIPFINAL    0x02    \/* skip finalfn, return state as-is *\/#define AGGSPLITOP_SERIALIZE    0x04    \/* apply serialfn to output *\/#define AGGSPLITOP_DESERIALIZE    0x08    \/* apply deserialfn to input *\/\/* Supported operating modes (i.e., useful combinations of these options): *\/typedef enum AggSplit{    \/* Basic, non-split aggregation: *\/    AGGSPLIT_SIMPLE = 0,    \/* Initial phase of partial aggregation, with serialization: *\/    AGGSPLIT_INITIAL_SERIAL = AGGSPLITOP_SKIPFINAL | AGGSPLITOP_SERIALIZE,    \/* Final phase of partial aggregation, with deserialization: *\/    AGGSPLIT_FINAL_DESERIAL = AGGSPLITOP_COMBINE | AGGSPLITOP_DESERIALIZE,} AggSplit;\/* Test whether an AggSplit value selects each primitive option: *\/#define DO_AGGSPLIT_COMBINE(as)        (((as) &amp; AGGSPLITOP_COMBINE) != 0)#define DO_AGGSPLIT_SKIPFINAL(as)    (((as) &amp; AGGSPLITOP_SKIPFINAL) != 0)#define DO_AGGSPLIT_SERIALIZE(as)    (((as) &amp; AGGSPLITOP_SERIALIZE) != 0)#define DO_AGGSPLIT_DESERIALIZE(as) (((as) &amp; AGGSPLITOP_DESERIALIZE) != 0)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 <code>AggSplit<\/code>, \u043d\u043e \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#8212; \u044d\u0442\u043e \u0431\u0438\u0442\u043e\u0432\u0430\u044f \u043c\u0430\u0441\u043a\u0430 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432 \u0432\u044b\u0448\u0435. \u0418\u0437 \u043d\u0438\u0445 \u0434\u0432\u0435 \u043c\u044b \u0443\u0436\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 &#8212; COMBINE \u0438 SKIPFINAL, \u043d\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0435\u0449\u0435 \u0434\u0432\u0435. \u041e\u043d\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\/\u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438 (\u043f\u0440\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438).<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044f \u044d\u0442\u0438 \u0447\u0435\u0442\u044b\u0440\u0435 \u0444\u043b\u0430\u0433\u0430, \u043c\u044b \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0440\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u0430 \u0443\u0437\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u044d\u0442\u0438\u043c\u0438 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f\u043c\u0438: <code>SIMPLE<\/code> &#8212; \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0443\u0437\u0435\u043b, <code>INITIAL_SERIAL<\/code> &#8212; Partial, <code>FINAL_DESERIAL<\/code> &#8212; Finalize.<\/p>\n<\/div>\n<\/details>\n<h4>ORDERED SET\/DISTINCT \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b<\/h4>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u0432\u0435\u0449\u044c &#8212; \u044d\u0442\u043e \u043e\u0441\u043e\u0431\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, ordered-set aggregate.<\/p>\n<blockquote>\n<p>\u0415\u0441\u0442\u044c \u0435\u0449\u0435 hypothetical-set aggregate, \u043d\u043e \u043e\u043d\u0438 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043b\u0430\u0434\u0443 \u0432 \u043e\u0434\u043d\u0443 \u0442\u043e\u043f\u043a\u0443<\/p>\n<\/blockquote>\n<p>\u0418\u0445 \u043e\u0442\u043b\u0438\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0438\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u0445\u043e\u0434. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0434\u0443 (<code>mode<\/code>) \u043d\u0435\u043b\u044c\u0437\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0432 \u043f\u043e\u0442\u043e\u043a\u0435, \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u0432\u0441\u044e \u0432\u044b\u0431\u043e\u0440\u043a\u0443.<\/p>\n<pre><code class=\"sql\">SELECT a, mode() WITHIN GROUP (ORDER BY b) FROM tbl GROUP BY a;         QUERY PLAN------------------------------ GroupAggregate   Group Key: a   -&gt;  Sort         Sort Key: a         -&gt;  Seq Scan on tbl<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0443\u0432\u0438\u0434\u0435\u043d\u043d\u044b\u0435 \u0433\u0440\u0443\u043f\u043f\u044b, \u044d\u0442\u043e \u043d\u0435 \u043a\u0430\u043a \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e \u043e\u0434\u043d\u043e\u0439. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438. \u041d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u0438\u0432\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0435 \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439, \u0442\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:<\/p>\n<ol>\n<li>\n<p>\u041f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c <em>\u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430<\/em>, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u043a\u043e\u0440\u0442\u0435\u0436 \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u044d\u0442\u043e\u0442 \u043c\u0430\u0441\u0441\u0438\u0432, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0430 \u043f\u0430\u043c\u044f\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u0425\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u0441\u0430\u043c \u043c\u0430\u0441\u0441\u0438\u0432. \u0420\u0430\u0437\u043c\u0435\u0440 \u0432\u0441\u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 (<code>AggStatePerGroup<\/code>) 10 \u0431\u0430\u0439\u0442, \u043d\u043e \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442 8 \u0431\u0430\u0439\u0442, \u0442\u043e \u0435\u0441\u0442\u044c \u0432 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c <em>\u043f\u043e\u0447\u0442\u0438 \u0432\u0434\u0432\u043e\u0435 \u043c\u0435\u043d\u044c\u0448\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432<\/em>, \u0445\u043e\u0442\u044f \u043f\u043e\u0434\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442.<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0446\u0435\u043b\u0443\u044e \u043a\u0443\u0447\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f ORDRED SET \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 <em>\u043d\u0435<\/em> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0442.\u0435. \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430. \u0418 \u0441 \u043d\u0435\u0439 \u0432\u0441\u0435 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c GS. \u0422\u043e\u0433\u0434\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a:<\/p>\n<ol>\n<li>\n<p>\u041f\u043e \u043d\u0430\u0447\u0430\u043b\u0443 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e OS \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>advance_aggregates<\/code>, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c, \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043a\u043e\u0440\u0442\u0435\u0436 \u0432 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0443\u0436\u0435 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430, \u0430 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0438 \u0441\u0430\u043c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 ORDERED SET \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u043c\u0438 &#8212; \u0441\u0430\u043c\u0443 \u043b\u043e\u0433\u0438\u043a\u0443 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u043c. \u0415\u0449\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0432 \u043a\u043e\u0434\u0435 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 &#8212; \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (\u043e\u0434\u0438\u043d <code>Datum<\/code>) \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 (\u043a\u043e\u0440\u0442\u0435\u0436). \u042d\u0442\u043e \u0447\u0438\u0441\u0442\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 &#8212; \u043a\u043e\u0440\u0442\u0435\u0436 \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 (\u0447\u0442\u043e \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u0445\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430). \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>tuplesort_begin_datum<\/code> &#8212; \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0430 <code>tuplesort_begin_heap<\/code> &#8212; \u0434\u043b\u044f \u043a\u043e\u0440\u0442\u0435\u0436\u0430 (\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439).<\/p>\n<pre><code class=\"cpp\">\/* \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f *\/\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L586 *\/static voidinitialize_aggregate(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate){   \/* \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 *\/    if (pertrans-&gt;aggsortrequired)    {        if (pertrans-&gt;sortstates[aggstate-&gt;current_set])            tuplesort_end(pertrans-&gt;sortstates[aggstate-&gt;current_set]);        if (pertrans-&gt;numInputs == 1)        {            Form_pg_attribute attr = TupleDescAttr(pertrans-&gt;sortdesc, 0);            pertrans-&gt;sortstates[aggstate-&gt;current_set] =                tuplesort_begin_datum(attr-&gt;atttypid,                                      pertrans-&gt;sortOperators[0],                                      pertrans-&gt;sortCollations[0],                                      pertrans-&gt;sortNullsFirst[0],                                      work_mem, NULL, TUPLESORT_NONE);        }        else            pertrans-&gt;sortstates[aggstate-&gt;current_set] =                tuplesort_begin_heap(pertrans-&gt;sortdesc,                                     pertrans-&gt;numSortCols,                                     pertrans-&gt;sortColIdx,                                     pertrans-&gt;sortOperators,                                     pertrans-&gt;sortCollations,                                     pertrans-&gt;sortNullsFirst,                                     work_mem, NULL, TUPLESORT_NONE);    }      \/* \u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 \u0438\u0437 AggStatePerTrans \u0432 AggStatePerGroup *\/}\/* \u0421\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 advance_aggregates *\/\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execExprInterp.c#L2251 *\/static Datum ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull){   EEO_SWITCH()   {        \/* ... *\/        EEO_CASE(EEOP_AGG_ORDERED_TRANS_DATUM)        {            ExecEvalAggOrderedTransDatum(state, op, econtext);            EEO_NEXT();        }        EEO_CASE(EEOP_AGG_ORDERED_TRANS_TUPLE)        {            ExecEvalAggOrderedTransTuple(state, op, econtext);            EEO_NEXT();        }          \/* ... *\/   }}\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/execExprInterp.c#L5808 *\/void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op, ExprContext *econtext){    AggStatePerTrans pertrans = op-&gt;d.agg_trans.pertrans;    int            setno = op-&gt;d.agg_trans.setno;    tuplesort_putdatum(pertrans-&gt;sortstates[setno], *op-&gt;resvalue, *op-&gt;resnull);}\/* \u0424\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f *\/\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L1306 *\/static void finalize_aggregates(AggState *aggstate, AggStatePerAgg peraggs, AggStatePerGroup pergroup){   \/* \u0421\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0445\u043e\u0434 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0434\u043b\u044f ORDERED SET \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 *\/   for (int transno = 0; transno &lt; aggstate-&gt;numtrans; transno++)    {        AggStatePerTrans pertrans = &amp;aggstate-&gt;pertrans[transno];        AggStatePerGroup pergroupstate = &amp;pergroup[transno];        if (pertrans-&gt;aggsortrequired)        {            if (pertrans-&gt;numInputs == 1)                process_ordered_aggregate_single(aggstate, pertrans, pergroupstate);            else                process_ordered_aggregate_multi(aggstate, pertrans, pergroupstate);        }    }       \/* \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 *\/    for (aggno = 0; aggno &lt; aggstate-&gt;numaggs; aggno++)    {        AggStatePerAgg peragg = &amp;peraggs[aggno];        int            transno = peragg-&gt;transno;        AggStatePerGroup pergroupstate = &amp;pergroup[transno];        finalize_aggregate(aggstate, peragg, pergroupstate,                           &amp;aggvalues[aggno], &amp;aggnulls[aggno]);    }}\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L847 *\/static void process_ordered_aggregate_single(AggState *aggstate,                                             AggStatePerTrans pertrans,                                             AggStatePerGroup pergroupstate){    \/* \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 *\/    tuplesort_performsort(pertrans-&gt;sortstates[aggstate-&gt;current_set]);    Datum newVal = &amp;fcinfo-&gt;args[1].value;    bool isNull = &amp;fcinfo-&gt;args[1].isnull;    \/* \u0412\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0441 \u0443\u0436\u0435 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0432\u0445\u043e\u0434\u043e\u043c *\/    while (tuplesort_getdatum(pertrans-&gt;sortstates[aggstate-&gt;current_set],                              true, false, newVal, isNull, &amp;newAbbrevVal))    {      advance_transition_function(aggstate, pertrans, pergroupstate);    }    tuplesort_end(pertrans-&gt;sortstates[aggstate-&gt;current_set]);    pertrans-&gt;sortstates[aggstate-&gt;current_set] = NULL;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u043e \u044d\u0442\u043e \u0435\u0449\u0435 \u043d\u0435 \u0432\u0441\u0435, \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043c \u043e <code>DISTINCT<\/code>. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>COUNT(DISTINCT a)<\/code>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430<code>a<\/code>. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 &#8212; \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435, \u0430 \u043c\u044b \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u043a\u043e\u0434\u0430, <code>DISTINCT<\/code> \u0438 <code>ORDERED SET<\/code> \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c &#8212; \u0438 \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u0447\u0442\u043e-\u0442\u043e \u0438\u0437 \u043d\u0438\u0445, \u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430.<\/p>\n<pre><code class=\"cpp\">static voidprocess_ordered_aggregate_single(AggState *aggstate,                                 AggStatePerTrans pertrans,                                 AggStatePerGroup pergroupstate){    Datum        oldVal = (Datum) 0;    bool         oldIsNull = true;    bool         haveOldVal = false;    bool         isDistinct = (pertrans-&gt;numDistinctCols &gt; 0);    Datum        newAbbrevVal = (Datum) 0;    Datum        oldAbbrevVal = (Datum) 0;    FunctionCallInfo fcinfo = pertrans-&gt;transfn_fcinfo;    Datum       *newVal;    bool        *isNull;    tuplesort_performsort(pertrans-&gt;sortstates[aggstate-&gt;current_set]);    newVal = &amp;fcinfo-&gt;args[1].value;    isNull = &amp;fcinfo-&gt;args[1].isnull;    while (tuplesort_getdatum(pertrans-&gt;sortstates[aggstate-&gt;current_set],                                    true, false, newVal, isNull, &amp;newAbbrevVal))    {        if (isDistinct &amp;&amp;            haveOldVal &amp;&amp;            ((oldIsNull &amp;&amp; *isNull) ||             (!oldIsNull &amp;&amp; !*isNull &amp;&amp;              oldAbbrevVal == newAbbrevVal &amp;&amp;              DatumGetBool(FunctionCall2Coll(&amp;pertrans-&gt;equalfnOne,                                             pertrans-&gt;aggCollation,                                             oldVal, *newVal)))))        {            \/* \u041d\u0430\u0434\u0435\u043d\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 - \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c *\/            MemoryContextSwitchTo(oldContext);            continue;        }        else        {            advance_transition_function(aggstate, pertrans, pergroupstate);               \/* \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0430 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 *\/            oldVal = *newVal;            oldAbbrevVal = newAbbrevVal;            oldIsNull = *isNull;            haveOldVal = true;        }    }    tuplesort_end(pertrans-&gt;sortstates[aggstate-&gt;current_set]);    pertrans-&gt;sortstates[aggstate-&gt;current_set] = NULL;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0438\u0448\u0435\u043d\u043a\u0430 \u043d\u0430 \u0442\u043e\u0440\u0442\u0435 &#8212; \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0434\u043b\u044f OS \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>\u0412 Postgres \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 ordered set \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432, \u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0432\u043e\u0442 \u0447\u0442\u043e &#8212; \u0443 \u0432\u0441\u0435\u0445 \u043d\u0438\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430:<\/p>\n<pre><code class=\"sql\">SELECT aggfnoid, aggtransfn, agginitval FROM pg_aggregate WHERE aggkind = 'o';          aggfnoid          |       aggtransfn       | agginitval ----------------------------+------------------------+------------ pg_catalog.percentile_disc | ordered_set_transition |  pg_catalog.percentile_cont | ordered_set_transition |  pg_catalog.percentile_cont | ordered_set_transition |  pg_catalog.percentile_disc | ordered_set_transition |  pg_catalog.percentile_cont | ordered_set_transition |  pg_catalog.percentile_cont | ordered_set_transition |  mode                       | ordered_set_transition | (7 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u0431\u0443\u0434\u0435\u0442 \u043d\u0438\u0436\u0435.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0442\u0440\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430, \u043d\u043e \u0443 \u0432\u0441\u0435\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0435\u0433\u043e\u2026<\/p>\n<pre><code class=\"sql\">SELECT b,       mode() WITHIN GROUP (ORDER BY cast(a as double precision)),       percentile_cont(0.7) WITHIN GROUP (ORDER BY cast(a as double precision)),       percentile_disc(0.7) WITHIN GROUP (ORDER BY cast(a as double precision))FROM tbl GROUP BY b;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u2026\u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e (<code>numtrans<\/code>), \u0445\u043e\u0442\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u0442\u0440\u0438 (<code>numaggs<\/code>).<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d7b\/436\/9a7\/d7b4369a70e7d937c2f74dda1a605fbe.png\" alt=\"numtrans \u0442\u043e\u043b\u044c\u043a\u043e 1, \u0430 numaggs 3\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/d7b\/436\/9a7\/d7b4369a70e7d937c2f74dda1a605fbe.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/d7b\/436\/9a7\/d7b4369a70e7d937c2f74dda1a605fbe.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>numtrans \u0442\u043e\u043b\u044c\u043a\u043e 1, \u0430 numaggs 3<\/figcaption><\/div>\n<\/figure>\n<h3>Index Aggregate<\/h3>\n<p>\u0412\u0441\u0435 \u044d\u0442\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u043d\u0435 \u0438\u0437 \u043f\u0440\u0430\u0437\u0434\u043d\u043e\u0433\u043e \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u0441\u0442\u0432\u0430. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u043d\u0438\u0433\u0438 \u201cMore Modern B-tree techniques\u201d (\u0430\u0432\u0442\u043e\u0440 \u0413\u0440\u0435\u0444\u0435 \u0413\u0435\u0442\u0446\/Graefe Goetz) \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0441\u0435\u043a\u0446\u0438\u044e \u043f\u0440\u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443 \u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044e. \u041e\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/arxiv.org\/pdf\/2010.00152\">\u201cEfficient sorting, duplicate removal, grouping, and aggregation\u201d<\/a>.<\/p>\n<blockquote>\n<p>\u0412 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u0432\u044b, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0440\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u201cModern B-tree techniques\u201d, \u043d\u043e \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0442\u0430\u043c \u043d\u0435\u0442<\/p>\n<\/blockquote>\n<h4>\u041e \u0447\u0435\u043c \u0441\u0442\u0430\u0442\u044c\u044f<\/h4>\n<p>\u0420\u0435\u0437\u044e\u043c\u0438\u0440\u0443\u044f \u0441\u0442\u0430\u0442\u044c\u044e &#8212; \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443 \u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u043d\u0434\u0435\u043a\u0441 \u043d\u0430 \u043b\u0435\u0442\u0443. \u041a\u043b\u044e\u0447 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 &#8212; \u0430\u0442\u0440\u0438\u0431\u0443\u0442 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438, \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#8212; \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435:<\/p>\n<ul>\n<li>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/www.cidrdb.org\/cidr2003\/program\/p1.pdf\">\u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 B-tree \u0438\u043d\u0434\u0435\u043a\u0441<\/a><\/p>\n<\/li>\n<li>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0431\u0449\u0438\u0439 \u043f\u0443\u043b \u0431\u0443\u0444\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u044d\u0442\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 (\u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438 \u0441 postgres &#8212; <code>shared_buffers<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0430 \u0434\u0438\u0441\u043a, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u0440\u043e\u0441\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c Wide merge &#8212; \u0441\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u043e\u0434\u043d\u0443, \u0442.\u0435. \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c merge, \u043d\u043e \u044d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0430 &#8212; \u0443 \u043d\u0435\u0433\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u0439 fan-in, \u0442.\u0435. \u0437\u0430 \u0440\u0430\u0437 \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 (\u0438\u0437-\u0437\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043f\u0430\u043c\u044f\u0442\u0438) \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u043f\u0440\u043e\u0445\u043e\u0434\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<blockquote>\n<p>\u041a\u0440\u043e\u043c\u0435 \u043d\u0438\u0445 \u0431\u044b\u043b\u0438 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435, \u043a\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0432\u0448\u0438\u0445 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e run (\u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438) \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 offset-value coding.<\/p>\n<\/blockquote>\n<p>\u042d\u0442\u0430 \u0438\u0434\u0435\u044f \u043c\u0435\u043d\u044f \u0441\u0438\u043b\u044c\u043d\u043e \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0438\u043b\u0430 \u0438 \u0434\u043e\u043b\u0433\u043e \u043d\u0435 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u043b\u0430, \u0438 \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0435\u043b \u0438 \u043d\u0430\u0447\u0430\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438.<\/p>\n<h4>\u041f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h4>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e \u0432 \u0433\u043e\u043b\u043e\u0432\u0443, &#8212; \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u043a\u0430\u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0441\u0442\u0430\u0442\u044c\u0435. \u041f\u0435\u0440\u0432\u0443\u044e \u043d\u0435\u0434\u0435\u043b\u044e \u044f \u0442\u0430\u043a \u0438 \u0434\u0435\u043b\u0430\u043b: \u201c\u043d\u0443\u0436\u0435\u043d \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 B-tree\u201d &#8212; \u0441\u0435\u043b \u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e, \u201c\u043d\u0443\u0436\u0435\u043d \u043e\u0434\u0438\u043d wide merge\u201d &#8212; \u043d\u0430\u043f\u0438\u0448\u0435\u043c.<\/p>\n<p>\u041d\u043e, \u043f\u043e\u043d\u044f\u0432, \u043a\u0430\u043a\u043e\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442, \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0440\u0430\u0437\u043c\u044b\u0448\u043b\u044f\u0442\u044c, \u0438 \u043a\u043e \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 &#8212; \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u043b\u044c\u0437\u044f (\u043e\u0447\u0435\u043d\u044c \u0442\u0440\u0443\u0434\u043d\u043e) \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432 Postgres. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e B-tree, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437\u0434\u0435\u0441\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a.<\/p>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 &#8212; \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u043c\u0435\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0438\u043f\u044b \u043c\u0435\u0436\u0434\u0443 \u0431\u044d\u043a\u044d\u043d\u0434\u0430\u043c\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 <em>\u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043d\u0430 \u0434\u0438\u0441\u043a<\/em><\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f (combinefn) &#8212; \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e merge<\/p>\n<\/li>\n<\/ul>\n<p>\u0422.\u0435. \u043f\u043e \u0444\u0430\u043a\u0442\u0443, \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b &#8212; \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c Partial\/Finalize. \u041d\u043e \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0438\u0445 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0431\u044b\u0442\u044c \u0438 \u0442\u043e\u0433\u0434\u0430 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0422\u0430\u043a \u043a\u0430\u043a \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u0437\u0430 \u043c\u043d\u043e\u0439 \u044f \u0440\u0435\u0448\u0438\u043b \u0437\u0430\u0434\u0430\u0447\u0443 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0445\u043e\u0436\u0438\u043c \u043d\u0430 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 &#8212; \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c, (\u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441), \u0430 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0430 \u0434\u0438\u0441\u043a.<\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441\u043e \u0441\u0431\u0440\u043e\u0441\u043e\u043c \u043d\u0430 \u0434\u0438\u0441\u043a. \u041c\u044b \u0438 \u0442\u0443\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 \u0432 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 &#8212; \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0430 \u0436\u0435 \u0441\u0430\u043c\u0430\u044f \u0438\u0434\u0435\u044f &#8212; \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 (\u0438\u043d\u0434\u0435\u043a\u0441) \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u043c\u0435\u0449\u0430\u043b\u0430\u0441\u044c \u0432 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<blockquote>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u043f\u0438\u0441\u044c\u043c\u043e \u0441 \u043f\u0430\u0442\u0447\u0430\u043c\u0438 <a href=\"https:\/\/www.postgresql.org\/message-id\/2b06b055-7f0d-42a7-ac0b-983ee92e239f%40tantorlabs.ru\">\u0432 \u044d\u0442\u043e\u043c \u043f\u0438\u0441\u044c\u043c\u0435<\/a>.<\/p>\n<\/blockquote>\n<details class=\"spoiler\">\n<summary>\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b<\/summary>\n<div class=\"spoiler__content\">\n<p>\u042f \u0441\u0440\u0430\u0437\u0443 \u043e\u043f\u0438\u0441\u0430\u043b \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043d\u0435 \u0434\u0430\u043b \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u043d\u0430\u0434 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430\u043c\u0438. \u042d\u0442\u043e \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0434\u0435\u0441\u044c. \u041f\u0435\u0440\u0432\u043e\u0435 &#8212; \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f B-tree. \u0412 \u0441\u0432\u043e\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0413\u0440\u0435\u0444\u0435 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 B-tree. \u041d\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u044f \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0435 \u0442\u0443\u0434\u0430 &#8212; \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b <a href=\"https:\/\/dblab.reutlingen-university.de\/paper\/2017_iiWAS_WriteOptimizedIndexingWithpartitionedBTrees.pdf\">\u201cWrite-Optimized Indexing with Partitioned B-Trees\u201d<\/a>, \u0430 \u043e\u043d\u0430 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0441\u043e\u0432\u0441\u0435\u043c \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0438 <em>\u043d\u0435<\/em> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043a\u0430\u043d &#8212; \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0447\u0435\u0447\u043d\u044b\u0439 \u043f\u043e\u0438\u0441\u043a. \u042f \u0442\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u043e\u043d\u044f\u043b, \u043a\u0430\u043a \u0432 \u044d\u0442\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0441\u043a\u0430\u043d\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 B+tree.<\/p>\n<blockquote>\n<p>\u0427\u0435\u0441\u0442\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0435 \u043d\u0430 \u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e. \u0411\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u043e\u0431\u0435\u0436\u0430\u043b\u0441\u044f \u043f\u043e \u0441\u0442\u0430\u0442\u044c\u0435 \u0413\u0440\u0435\u0444\u0435 \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0432\u044b\u0434\u043e\u0445\u043d\u0443\u043b &#8212; \u0435\u0435 \u0442\u043e\u0436\u0435 \u043d\u0435 \u0442\u0430\u043a-\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043d\u0435\u0439 \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e.<\/p>\n<\/blockquote>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u0447\u0442\u043e \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c. \u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043f\u0440\u0438 \u043d\u0435\u0445\u0432\u0430\u0442\u043a\u0435 \u043f\u0430\u043c\u044f\u0442\u0438:<\/p>\n<ol>\n<li>\n<p>\u0412\u0441\u044e \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0438, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u044b (\u043f\u043e\u0434\u0445\u043e\u0434 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f)<\/p>\n<\/li>\n<\/ol>\n<p>\u042f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u043c, \u0432\u0435\u0434\u044c \u043d\u0435 \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0418 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0438 \u043e\u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435.<\/p>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435: \u043a\u0430\u043a \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438. \u0422\u0443\u0442 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e, \u0438 \u043c\u044b, \u043f\u043e \u0441\u0443\u0442\u0438, \u043c\u043e\u0436\u0435\u043c \u043b\u0438\u0431\u043e \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0432\u0441\u0435, \u0430 \u0437\u0430\u0442\u0435\u043c \u0442\u0430\u043a\u0436\u0435 \u0432\u0441\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c, \u043b\u0438\u0431\u043e \u0437\u0430\u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438 \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u0438\u0445 \u043d\u0430 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 (\u043f\u043e\u0434\u0445\u043e\u0434 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f). \u042f \u0432\u044b\u0431\u0440\u0430\u043b \u0432\u0442\u043e\u0440\u043e\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u043e\u0434\u0445\u043e\u0434 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0435\u0435 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043b\u0438\u0448\u043d\u0435\u0433\u043e IO. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437\u0434\u0435\u0441\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u044d\u0442\u0438\u043c \u0441\u0430\u043c\u044b\u043c \u043c\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0418 \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0438, \u043d\u043e \u044f \u0441\u0447\u0438\u0442\u0430\u044e, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0442\u0438\u043f\u043e\u0432 \u0442\u0430\u043a\u0438\u043c\u0438 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<blockquote>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c-\u0442\u043e \u0432\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f &#8212; \u0431\u0438\u0442\u0432\u0430 \u0441 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441\u0430\u043c\u0438. \u0412 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435, \u044f \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0430\u043c\u0438 \u0442\u0438\u043f\u044b &#8212; \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0418 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0438 \u0418 \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0438. \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 &#8212; \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b (\u0438\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435) &#8212; \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u043c\u0438.<\/p>\n<\/blockquote>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441\u044b \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u043e\u0444\u043e\u0440\u043c\u0438\u0442\u044c, \u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0434\u0432\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u0430:<\/p>\n<ol>\n<li>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c <em>\u043a\u043e\u0440\u0442\u0435\u0436<\/em> \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u043a\u0430\u0436\u0434\u0443\u044e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044e \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u043b\u044f \u043d\u0435\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <\/p>\n<ul>\n<li>\n<p>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0442\u0438\u043f\u044b: \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0438 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c <em>\u0438\u043d\u0434\u0435\u043a\u0441<\/em> (\u0441 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432), \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0430 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0441\u043b\u0438\u044f\u043d\u0438\u0435 \u0441 \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f (combine) <\/p>\n<ul>\n<li>\n<p>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b: \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u043c\u0438 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c\u044b\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0434\u0445\u043e\u0434\u044b \u0440\u0430\u0437\u043d\u044f\u0442\u0441\u044f, \u0438 \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u043f\u0435\u0440\u0432\u044b\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0433\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, &#8212; \u0432\u0441\u0435 \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0433\u043e\u0442\u043e\u0432\u043e. \u0412\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u044f \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b.<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u0445\u043e\u0442\u044f \u044d\u0442\u043e \u0434\u0430\u0436\u0435 \u043d\u0435 \u0432\u043e\u043f\u0440\u043e\u0441, \u0430 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435, &#8212; \u044d\u0442\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 GROUPING SETS. \u0421\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0443\u0437\u043b\u0435 \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0418 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443, \u0418 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443, \u043d\u043e \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043c\u043d\u043e\u0433\u043e GS, \u0442\u043e \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c <code>ORDER BY<\/code> \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432, \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 GS. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u2026<\/p>\n<pre><code class=\"sql\">SELECT a, b, c, d, e FROM tbl GROUP BY GROUPING SETS((a, c), (b, d, e), (a, b));<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u2026\u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0432 \u0442\u043e\u043c \u0436\u0435 \u0443\u0437\u043b\u0435, \u0442.\u043a. \u0442\u0440\u0435\u0442\u0438\u0439 GS \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0438\u0437 \u0434\u0432\u0443\u0445 \u0434\u0440\u0443\u0433\u0438\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044f\u0432\u043d\u0443\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0432\u0441\u0435\u0445 GS, \u0442.\u0435. \u043d\u0443\u0436\u0435\u043d \u044f\u0432\u043d\u044b\u0439 \u0443\u0437\u0435\u043b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u0440\u0438\u043d\u044f\u043b \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e 1 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443\/GS.<\/p>\n<h4>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h4>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439, &#8212; \u0434\u0430\u0442\u044c \u0438\u043c\u044f. \u042f \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u201cIndex Aggregate\u201d, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043d\u0430\u0448\u0430 \u0438\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u043d\u0434\u0435\u043a\u0441. \u0421\u0435\u0439\u0447\u0430\u0441 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 B+ \u0434\u0435\u0440\u0435\u0432\u043e, \u043d\u043e (\u0441\u043f\u043e\u0439\u043b\u0435\u0440) \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u0421\u0430\u043c\u044b\u0439 \u043f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433 &#8212; \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0432 \u043a\u043e\u0434, \u0442.\u0435. \u0432 \u0441\u0430\u043c\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">typedef enum AggStrategy{    AGG_PLAIN,                    \/* simple agg across all input rows *\/    AGG_SORTED,                    \/* grouped agg, input must be sorted *\/    AGG_HASHED,                    \/* grouped agg, use internal hashtable *\/    AGG_MIXED,                    \/* grouped agg, hash and sort both used *\/    AGG_INDEX,                    \/* grouped agg, build index for input *\/} AggStrategy;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u043c\u0438 \u0442\u0440\u0438 \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<ol>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u043d\u0434\u0435\u043a\u0441\u0430<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0434 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0432\u044b\u0448\u0435\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430 (\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0438 <code>EXPLAIN<\/code>)<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u043d\u0430\u0434\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430. \u041f\u043e\u0432\u0442\u043e\u0440\u044e \u0435\u0449\u0435 \u0440\u0430\u0437 &#8212; \u044d\u0442\u043e B+ \u0434\u0435\u0440\u0435\u0432\u043e. \u0427\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435 &#8212; \u043d\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, &#8212; \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 (\u0442\u0430\u043a \u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0438 \u0434\u043b\u044f \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c). \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0441\u0430\u043c\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443.<\/p>\n<pre><code class=\"cpp\">\/* * Representation of tuple in index.  It stores both tuple and * first key information.  If key abbreviation is used, then this * first key stores abbreviated key. *\/typedef struct TupleIndexEntryData{    MinimalTuple tuple;       \/* actual stored tuple *\/    Datum        key1;        \/* value of first key *\/    bool         isnull1;     \/* first key is null *\/} TupleIndexEntryData;typedef TupleIndexEntryData *TupleIndexEntry;\/* * Btree node of tuple index. Common for both internal and leaf nodes. *\/typedef struct TupleIndexNodeData{    \/* amount of tuples in the node *\/    int ntuples;\/* * Maximal amount of tuples stored in tuple index node. * * NOTE: use 2^n - 1 count, so all all tuples will fully utilize cache lines *       (except first because of 'ntuples' padding) *\/#define TUPLE_INDEX_NODE_MAX_ENTRIES  63    \/*     * array of tuples for this page.     *     * for internal node these are separator keys.     * for leaf nodes actual tuples.     *\/    TupleIndexEntry tuples[TUPLE_INDEX_NODE_MAX_ENTRIES];    \/*     * for internal nodes this is an array with size     * TUPLE_INDEX_NODE_MAX_ENTRIES + 1 - pointers to nodes below.     *     * for leaf nodes this is an array of 1 element - pointer to sibling     * node required for iteration     *\/    struct TupleIndexNodeData *pointers[FLEXIBLE_ARRAY_MEMBER];} TupleIndexNodeData;typedef TupleIndexNodeData *TupleIndexNode;#define SizeofTupleIndexInternalNode \\      (offsetof(TupleIndexNodeData, pointers) \\    + (TUPLE_INDEX_NODE_MAX_ENTRIES + 1) * sizeof(TupleIndexNode))#define SizeofTupleIndexLeafNode \\    (offsetof(TupleIndexNodeData, pointers) + sizeof(TupleIndexNode))typedef struct TupleIndexData{   TupleDesc    tupDesc;       \/* descriptor for stored tuples *\/   TupleIndexNode root;        \/* root of the tree *\/   int        height;                \/* current tree height *\/   int        ntuples;               \/* number of tuples in index *\/   int        nkeys;                 \/* amount of keys in tuple *\/   SortSupport      sortKeys;    \/* support functions for key comparison *\/   MemoryContext    tuplecxt;    \/* memory context containing tuples *\/   MemoryContext    nodecxt;     \/* memory context containing index nodes *\/   Size       additionalsize;        \/* size of additional data for tuple *\/   int        abbrevNext;            \/* next time we should check abbreviation                                      * optimization efficiency *\/   bool       abbrevUsed;            \/* true if key abbreviation optimization                                      * was ever used *\/   Oid        abbrevSortOp;          \/* sort operator for first key *\/} TupleIndexData;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<blockquote>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0432 <a href=\"https:\/\/www.postgresql.org\/message-id\/attachment\/189612\/v4-0001-add-in-memory-btree-tuple-index.patch\">\u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0430\u0442\u0447\u0435<\/a><\/p>\n<\/blockquote>\n<details class=\"spoiler\">\n<summary>Key Abbreviation<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043f\u043e\u043b\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u044f\u0441\u043d\u0430, \u043a\u0440\u043e\u043c\u0435 \u0442\u0440\u0435\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0432 <code>TupleIndexData<\/code>. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 <code>abbrev<\/code>? \u042d\u0442\u043e \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 <code>abbreviation<\/code> \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439. \u0414\u0430\u043b\u0435\u0435: \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 Postgres \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u0438\u043f\u043e\u043c <code>Datum<\/code>. \u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0448\u0438\u0440\u043e\u043a\u043e\u0435 (\u0431\u0430\u0439\u0442\u044b) \u0447\u0438\u0441\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0442\u0438\u043f\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\/by-value &#8212; \u0435\u0441\u043b\u0438 \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0447\u0438\u0441\u043b\u0430, \u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0438\u043f \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0439\/by-ref &#8212; Datum \u043d\u0430\u0434\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0441\u0430\u043c\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041d\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0447\u0435\u043d\u044c \u0447\u0430\u0441\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043d\u0435 \u0440\u0435\u0434\u043a\u0438 \u0441\u043b\u0443\u0447\u0430\u0438, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043f\u043e \u0432\u0441\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u0438\u0448\u044c \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430.<\/p>\n<p>\u042d\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0440\u0435\u0448\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 &#8212; key abbreviation (\u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0430). \u0421\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0439 \u0442\u0438\u043f \u043c\u043e\u0436\u0435\u0442 \u201c\u0441\u0436\u0430\u0442\u044c\u201d \u0441\u0435\u0431\u044f \u0434\u043e by-value Datum\u2019\u0430 (\u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430), \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0441\u0436\u0430\u0442\u043e\u0435. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0434\u0432\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u043e, \u043d\u043e \u0432\u0441\u0435 \u0436\u0435 \u0435\u0441\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0441\u0436\u0430\u0442\u044b\u0445 \u043a\u043b\u044e\u0447\u0435\u0439 \u0441\u043e\u043e\u0431\u0449\u0438\u043b\u0430, \u0447\u0442\u043e \u043e\u043d\u0438 \u0440\u0430\u0432\u043d\u044b, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0436\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0441\u0436\u0430\u0442\u0438\u044f, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c <code>BTSORTSUPPORT_PROC<\/code> \u043e\u043f\u043e\u0440\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0443 B+\u0434\u0435\u0440\u0435\u0432\u0430. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0435\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445: \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0436\u0430\u0442\u0438\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430 \u0438 \u0442.\u0434. \u041d\u0430\u0433\u043b\u044f\u0434\u043d\u0435\u0435 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 <code>numeric<\/code>. \u042d\u0442\u043e \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u0442\u0438\u043f \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439. \u041f\u0440\u0438\u0447\u0435\u043c \u0435\u0433\u043e \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c &#8212; \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u043e\u043d \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043a\u0430\u043a \u043c\u0430\u0441\u0441\u0438\u0432 \u0447\u0438\u0441\u0435\u043b, \u0430 \u043d\u0435 <code>int<\/code>\/<code>float<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043e\u043f\u043e\u0440\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>numeric_sortsupport<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442:<\/p>\n<ul>\n<li>\n<p>\u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 &#8212; <code>numeric_cmp_abbrev<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/62d6c7d3df6287f1bd83199c1a746e50d31571a0\/src\/backend\/utils\/adt\/numeric.c#L2322\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a>)<\/p>\n<\/li>\n<li>\n<p>\u0441\u0436\u0430\u0442\u0438\u0435 &#8212; <code>numeric_abbrev_convert<\/code> (<a href=\"https:\/\/github.com\/postgres\/postgres\/blob\/62d6c7d3df6287f1bd83199c1a746e50d31571a0\/src\/backend\/utils\/adt\/numeric.c#L2171\">\u0441\u0441\u044b\u043b\u043a\u0430<\/a>)<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0430 \u0432\u043e\u0442 \u044d\u0442\u043e\u043c:<\/p>\n<pre><code class=\"sql\">CREATE TABLE numerictbl(num numeric);INSERT INTO numerictbl SELECT (random() * 1000000000)::numeric FROM generate_series(1, 1000000);EXPLAIN (COSTS OFF) SELECT num FROM numerictbl ORDER BY num;          QUERY PLAN------------------------------- Sort   Sort Key: num   -&gt;  Seq Scan on numerictbl(3 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u0440\u0430\u0437\u0443 (\u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u044f), \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0434\u043d\u043e \u0432\u0440\u0435\u043c\u044f:<\/p>\n<pre><code class=\"sql\">EXPLAIN (COSTS OFF, ANALYZE) SELECT num FROM numerictbl ORDER BY num;                                    QUERY PLAN                              ---------------------------------------------------------------------------------- Sort (actual time=517.539..911.922 rows=1000000.00 loops=1)   Sort Key: num   Sort Method: external merge  Disk: 16440kB   Buffers: shared hit=5406, temp read=2055 written=2060   -&gt;  Seq Scan on numerictbl (actual time=0.019..92.871 rows=1000000.00 loops=1)         Buffers: shared hit=5406 Planning Time: 0.045 ms Execution Time: 948.386 ms(8 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0432\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u044f\u043b\u043e \u0447\u0443\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0436\u0430\u0442\u0438\u0435 \u0434\u043b\u044f <code>numeric<\/code>. \u042f \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 (\u043c\u043d\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0449\u0435). \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u043b\u043e\u2026<\/p>\n<pre><code class=\"sql\">EXPLAIN (COSTS OFF, ANALYZE) SELECT num FROM numerictbl ORDER BY num;                                    QUERY PLAN                              ---------------------------------------------------------------------------------- Sort (actual time=2064.322..2458.596 rows=1000000.00 loops=1)   Sort Key: num   Sort Method: external merge  Disk: 16440kB   Buffers: shared hit=94 read=5312, temp read=2055 written=2060   -&gt;  Seq Scan on numerictbl (actual time=0.097..88.330 rows=1000000.00 loops=1)         Buffers: shared hit=94 read=5312 Planning Time: 0.042 ms Execution Time: 2495.272 ms(8 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u2026 \u0432 2,5 \u0440\u0430\u0437\u0430 \u0434\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u044d\u0442\u0430 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0430 &#8212; \u043c\u044b \u0442\u0440\u0430\u0442\u0438\u043c \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0441\u0436\u0430\u0442\u0438\u0435. \u0415\u0441\u043b\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u0432 \u043d\u0430\u0448\u0443 \u043f\u043e\u043b\u044c\u0437\u0443 (\u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0447\u0430\u0441\u0442\u043e), \u0442\u043e \u043c\u044b \u0441\u043a\u043e\u0440\u0435\u0435 \u0434\u0435\u0433\u0440\u0430\u0434\u0438\u0440\u0443\u0435\u043c. \u0427\u0442\u043e\u0431\u044b \u0442\u0430\u043a\u043e\u0433\u043e \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0438 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0436\u0435 <code>numeric<\/code> &#8212; \u044d\u0442\u043e <code>numeric_abbrev_abort<\/code>. \u0417\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044d\u0442\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0445\u043e\u0436\u0430 &#8212; \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e, \u0435\u0441\u043b\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0443\u043f\u0430\u043b\u043e \u043d\u0438\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u043e\u0433\u0430. \u042d\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u0434\u043e\u043c, \u0447\u0435\u043c \u0441\u043b\u043e\u0432\u0430\u043c\u0438:<\/p>\n<pre><code class=\"cpp\">\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/utils\/adt\/numeric.c#L2233 *\/static boolnumeric_abbrev_abort(int memtupcount, SortSupport ssup){    NumericSortSupport *nss = ssup-&gt;ssup_extra;    double        abbr_card;    if (memtupcount &lt; 10000 || nss-&gt;input_count &lt; 10000 || !nss-&gt;estimating)        return false;    abbr_card = estimateHyperLogLog(&amp;nss-&gt;abbr_card);    \/*     * If we have &gt;100k distinct values, then even if we were sorting many     * billion rows we'd likely still break even, and the penalty of undoing     * that many rows of abbrevs would probably not be worth it. Stop even     * counting at that point.     *\/    if (abbr_card &gt; 100000.0)    {        nss-&gt;estimating = false;        return false;    }    \/*     * Target minimum cardinality is 1 per ~10k of non-null inputs.  (The     * break even point is somewhere between one per 100k rows, where     * abbreviation has a very slight penalty, and 1 per 10k where it wins by     * a measurable percentage.)  We use the relatively pessimistic 10k     * threshold, and add a 0.5 row fudge factor, because it allows us to     * abort earlier on genuinely pathological data where we've had exactly     * one abbreviated value in the first 10k (non-null) rows.     *\/    if (abbr_card &lt; nss-&gt;input_count \/ 10000.0 + 0.5)    {        return true;    }    return false;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a \u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0432\u0441\u0435 &#8212; key abbreviation \u044f \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0432 \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u043d\u0434\u0435\u043a\u0441\u0430.<\/p>\n<\/div>\n<\/details>\n<p>\u0418\u043d\u0434\u0435\u043a\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 &#8212; \u043a\u043e\u0434\u0443 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438. \u0412\u043e\u043e\u0431\u0449\u0435, \u0435\u0435 \u043b\u043e\u0433\u0438\u043a\u0430 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043d\u0435 \u0441\u0442\u0430\u043b \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u043f\u0440\u043e\u0441\u0442\u043e (\u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u043e) \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b \u044d\u0442\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e:<\/p>\n<ul>\n<li>\n<p><code>agg_fill_index<\/code> &#8212; \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 (\u0430\u043d\u0430\u043b\u043e\u0433 <code>agg_fill_hash_table<\/code>)<\/p>\n<\/li>\n<li>\n<p><code>lookup_index_entries<\/code> &#8212; \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c (\u0430\u043d\u0430\u043b\u043e\u0433 <code>lookup_hash_entries<\/code>)<\/p>\n<\/li>\n<li>\n<p><code>indexagg_refill_batch<\/code> &#8212; \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u0440\u043e\u0441\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a (\u0430\u043d\u0430\u043b\u043e\u0433 <code>agg_refill_hash_table<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u0434 \u0441\u0431\u0440\u043e\u0441\u0430 &#8212; \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0438 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (<code>agg_spill_tuple<\/code>)<\/p>\n<\/li>\n<\/ul>\n<blockquote>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 2 \u043f\u0430\u0442\u0447\u0430\u0445: <a href=\"https:\/\/www.postgresql.org\/message-id\/attachment\/189613\/v4-0002-change-field-prefix-from-hash_-to-spill_-in-AggSt.patch\">\u043f\u0435\u0440\u0432\u044b\u0439<\/a> &#8212; \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u0438 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435 (\u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0435), \u0430 \u0432\u043e <a href=\"https:\/\/www.postgresql.org\/message-id\/attachment\/189614\/v4-0003-introduce-AGG_INDEX-grouping-strategy-node.patch\">\u0432\u0442\u043e\u0440\u043e\u043c<\/a> \u0443\u0436\u0435 \u0441\u0430\u043c\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f. \u0421\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0440\u0435\u0432\u044c\u044e.<\/p>\n<\/blockquote>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0435\u0433\u043e \u0447\u0435\u0440\u0442\u044b: \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u043d\u043e \u0432\u0441\u0435 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u0440\u0438\u0445\u043e\u0434\u043e\u043c \u0441\u0431\u0440\u043e\u0441\u0430\/\u043d\u0435\u0445\u0432\u0430\u0442\u043a\u0438 \u043f\u0430\u043c\u044f\u0442\u0438. \u041e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0438\u0434\u0435\u044e \u044f \u043e\u043f\u0438\u0441\u0430\u043b: \u0434\u0435\u043b\u0430\u0435\u043c \u043a\u0430\u043a \u0432 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 &#8212; \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0445\u0435\u0448 \u0434\u043b\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438, \u0430 \u0437\u0430\u0442\u0435\u043c \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u0441\u0432\u043e\u0438 \u0431\u0430\u043a\u0435\u0442\u044b. \u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0435\u0441\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u044f \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0438\u0437 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u044d\u0442\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0430\u0442\u0447\u0430 &#8212; \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435, \u0443\u0447\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u0442.\u0434. &#8212; \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e \u0432 \u043d\u0435\u0439 \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u044f \u043e\u043f\u0443\u0449\u0443. \u0425\u043e\u0442\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u0432\u0441\u0435 \u0436\u0435 \u0435\u0441\u0442\u044c.<\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435 &#8212; \u043a\u0430\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043b\u0438\u044f\u043d\u0438\u0435 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439. \u0412 \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438, \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0445\u0435\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043c\u043e\u0433\u043b\u0438 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u044c, \u0442.\u043a. \u043c\u044b \u0435\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e &#8212; \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f. \u0412 Postgres \u0434\u043b\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 (\u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0438\u0434\u043e\u0432) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\/\u043e\u0431\u044a\u0435\u043a\u0442 <code>tuplesort<\/code>, \u0438 \u0432 \u043d\u0435\u0439 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0441\u043b\u0438\u044f\u043d\u0438\u0435\u043c. \u0422\u0430\u043a \u043a\u0430\u043a \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u0442\u043e \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u0435.<\/p>\n<p>\u0421\u0430\u043c \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0435\u0439\u0442-\u043c\u0430\u0448\u0438\u043d\u044b \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438 &#8212; \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 (\u0437\u0430\u043f\u0438\u0441\u044c) \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 (\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 + \u0447\u0442\u0435\u043d\u0438\u0435). \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 &#8212; \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u0441 \u0435\u0435 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u0435. \u042d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443 &#8212; \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043d\u043e\u0432\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c <code>tuplemerge_<\/code> (\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <code>tuplesort_<\/code>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u0435.<\/p>\n<p>\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f (\u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e) \u043e\u0442 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0441\u043b\u0438\u044f\u043d\u0438\u0435\u043c (\u0442\u043e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 <code>tuplesort<\/code>) \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0443\u0436\u0435 \u0437\u043d\u0430\u0435\u043c, \u0433\u0434\u0435 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043b\u0438\u0448\u043d\u044e\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f &#8212; <code>tuplesort_put_*<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u043b\u0430\u0434\u0435\u0442 \u043a\u043e\u0440\u0442\u0435\u0436 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c, \u0430 \u0441\u0431\u0440\u043e\u0441 \u043d\u0430 \u0434\u0438\u0441\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442.<\/p>\n<p>\u0413\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c (\u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a \u043d\u0430\u0437\u0432\u0430\u0442\u044c) \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u044e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f &#8212; \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0441\u0430\u043c\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0447\u0442\u043e \u0438 \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0434\u0438\u0441\u043a. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0440\u0430\u043c\u043b\u044f\u044e\u0442 \u043a\u043e\u0434 \u0437\u0430\u043f\u0438\u0441\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 (\u0443\u0436\u0435 \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445):<\/p>\n<ul>\n<li>\n<p><code>tuplemerge_start_run<\/code> &#8212; \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0442\u0435\u0439\u043f \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438<\/p>\n<\/li>\n<li>\n<p><code>tuplemerge_end_run<\/code> &#8212; \u0437\u0430\u043f\u0435\u0447\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0442\u0435\u0439\u043f (\u043f\u043e\u043c\u0435\u0447\u0430\u0435\u0442 \u0435\u0433\u043e \u043a\u043e\u043d\u0435\u0446)<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0442\u043e\u0440\u043e\u0435 &#8212; \u043d\u0430\u0434\u043e \u0437\u043d\u0430\u0442\u044c, <em>\u0447\u0442\u043e<\/em> \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c. \u042d\u0442\u043e \u043c\u044b \u0443\u0436\u0435 \u043e\u0431\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u0432\u044b\u0448\u0435 &#8212; \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u0440\u0442\u0435\u0436 \u043f\u043e\u0441\u043b\u0435 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432, \u043d\u043e \u044d\u0442\u043e \u0435\u0449\u0435 \u043d\u0435 \u043a\u043e\u043d\u0435\u0446. \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c, \u043a\u043e\u0440\u0442\u0435\u0436 \u0435\u0441\u0442\u044c \u044d\u0442\u0430\u043f \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 &#8212; <code>project_aggregates<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442 <code>HAVING<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043c\u044b \u043d\u0435 \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u0435, \u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442\u0430.<\/p>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435\u0432\u0435\u043b\u0438\u043a\u0430, \u043d\u043e \u0434\u0430\u0436\u0435 \u0443 \u043d\u0435\u0435 \u0435\u0441\u0442\u044c \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0439 \u043a\u0430\u043c\u0435\u043d\u044c. \u041a\u0440\u0430\u0439\u043d\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 &#8212; \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u043d\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u042d\u0442\u043e \u043d\u0435 \u0432\u044b\u0434\u0443\u043c\u0430\u043d\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442 \u043e\u0447\u0435\u043d\u044c \u0441\u0435\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439. \u0421 \u044d\u0442\u0438\u043c \u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0438 \u0441\u0430\u043c\u0443 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u044d\u0442\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c. \u041d\u043e \u0432 \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u044f \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0431\u0443\u0434\u0443, \u0442.\u043a. \u0438 \u0440\u0430\u043d\u0435\u0435 \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0438. \u0412\u0441\u044f \u044d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 <a href=\"https:\/\/www.postgresql.org\/message-id\/attachment\/189615\/v4-0004-make-use-of-IndexAggregate-in-planner-and-explain.patch\">\u0447\u0435\u0442\u0432\u0435\u0440\u0442\u043e\u043c \u043f\u0430\u0442\u0447\u0435<\/a>.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0436\u0435 \u0447\u0430\u0441\u0442\u044c &#8212; \u044d\u0442\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0439 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438. \u041d\u043e, \u043a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438, \u0435\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0438 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043b\u043e\u0433\u0438\u043a\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0435\u0442. \u042d\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 <a href=\"https:\/\/www.postgresql.org\/message-id\/attachment\/189616\/v4-0005-add-support-for-Partial-IndexAggregate.patch\">\u043f\u0430\u0442\u0447<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0411\u0430\u0433, \u043e\u0431\u043c\u0430\u043d\u0443\u0432\u0448\u0438\u0439 \u043c\u0435\u043d\u044f, \u0430 \u044f &#8212; \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b TPC-H, \u0442.\u043a. \u043e\u043d \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0439 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438 \u044f \u0435\u0449\u0435 \u0440\u0430\u0437 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u0442\u0435\u0441\u0442 \u0438 \u043d\u0435 \u043f\u043e\u0432\u0435\u0440\u0438\u043b \u0441\u0432\u043e\u0438\u043c \u0433\u043b\u0430\u0437\u0430\u043c: \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u043f\u043b\u0430\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 Partial IndexAggregate. \u0418 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a: \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441\u043d\u0438\u0437\u0438\u043b\u043e\u0441\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c \u0432\u0434\u0432\u043e\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0440\u0438\u043d\u0430\u0434\u0446\u0430\u0442\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0443\u0441\u043a\u043e\u0440\u0438\u043b\u0441\u044f \u0441 20 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u043e 10.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u043b\u0430\u043d \u0432\u0430\u043d\u0438\u043b\u044c\u043d\u044b\u0439:<\/p>\n<pre><code class=\"sql\">                                                     QUERY PLAN                                                --------------------------------------------------------------------------------------------------------------------- Limit   -&gt;  Sort         Sort Key: orders.o_totalprice DESC, orders.o_orderdate         -&gt;  GroupAggregate               Group Key: customer.c_custkey, orders.o_orderkey               -&gt;  Merge Join                     Merge Cond: (orders.o_custkey = customer.c_custkey)                     -&gt;  Gather Merge                           Workers Planned: 4                           -&gt;  Sort                                 Sort Key: orders.o_custkey, orders.o_orderkey                                 -&gt;  Nested Loop                                       -&gt;  Merge Join                                             Merge Cond: (orders.o_orderkey = lineitem_1.l_orderkey)                                             -&gt;  Parallel Index Scan using orders_pkey on orders                                             -&gt;  GroupAggregate                                                   Group Key: lineitem_1.l_orderkey                                                   Filter: (sum(lineitem_1.l_quantity) &gt; '314'::numeric)                                                   -&gt;  Index Scan using idx_lineitem_orderkey on lineitem lineitem_1                                       -&gt;  Index Scan using idx_lineitem_orderkey on lineitem                                             Index Cond: (l_orderkey = orders.o_orderkey)                     -&gt;  Index Scan using customer_pkey on customer(22 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0432\u043e\u0442 \u043f\u043e\u0441\u043b\u0435:<\/p>\n<pre><code class=\"sql\">                                               QUERY PLAN                                         -------------------------------------------------------------------------------------------------------- Limit   -&gt;  Sort         Sort Key: orders.o_totalprice DESC, orders.o_orderdate         -&gt;  Finalize GroupAggregate               Group Key: customer.c_custkey, orders.o_orderkey               -&gt;  Nested Loop                     Join Filter: (orders.o_orderkey = lineitem_1.l_orderkey)                     -&gt;  Merge Join                           Merge Cond: (orders.o_custkey = customer.c_custkey)                           -&gt;  Nested Loop                                 Join Filter: (orders.o_orderkey = lineitem.l_orderkey)                                 -&gt;  Gather Merge                                       Workers Planned: 4                                       -&gt;  Incremental Sort                                             Sort Key: orders.o_custkey, orders.o_orderkey                                             Presorted Key: orders.o_custkey                                             -&gt;  Parallel Index Scan using idx_orders_custkey on orders                                 -&gt;  Materialize                                       -&gt;  Partial GroupAggregate                                             Group Key: lineitem.l_orderkey                                             -&gt;  Index Scan using idx_lineitem_orderkey on lineitem                           -&gt;  Index Scan using customer_pkey on customer                     -&gt;  Finalize GroupAggregate                           Group Key: lineitem_1.l_orderkey                           Filter: (sum(lineitem_1.l_quantity) &gt; '314'::numeric)                           -&gt;  Gather Merge                                 Workers Planned: 4                                 -&gt;  Partial IndexAggregate                                       Group Key: lineitem_1.l_orderkey                                       -&gt;  Parallel Seq Scan on lineitem lineitem_1(30 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0435\u0441\u0442\u044b &#8212; \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0435\u0439 \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <em>Partial<\/em> IndexAggregate. \u0422\u0443\u0442 \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u043e\u043b\u043e\u0442\u0430\u044f \u0436\u0438\u043b\u0430. \u0412\u043e\u0442 \u043e\u043d, \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u0435\u0445 \u0441\u043f\u0430\u0441\u0435\u0442. \u041d\u043e \u043f\u043e\u0442\u043e\u043c \u044f \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u0435\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0430 \u043f\u043b\u0430\u043d, \u0441 \u0438\u0445 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438:<\/p>\n<pre><code class=\"sql\">                                                                       QUERY PLAN                                                                 -------------------------------------------------------------------------------------------------------------------------------------------------------- Limit  (cost=NaN..NaN rows=1 width=71)   -&gt;  Sort  (cost=NaN..NaN rows=1 width=71)         Sort Key: orders.o_totalprice DESC, orders.o_orderdate         -&gt;  Finalize GroupAggregate  (cost=-Infinity..NaN rows=1 width=71)               Group Key: customer.c_custkey, orders.o_orderkey               -&gt;  Nested Loop  (cost=-Infinity..NaN rows=1 width=71)                     Join Filter: (orders.o_orderkey = lineitem_1.l_orderkey)                     -&gt;  Merge Join  (cost=1028.29..141008138077.91 rows=411897 width=75)                           Merge Cond: (orders.o_custkey = customer.c_custkey)                           -&gt;  Nested Loop  (cost=1026.66..141008054180.05 rows=411897 width=56)                                 Join Filter: (orders.o_orderkey = lineitem.l_orderkey)                                 -&gt;  Gather Merge  (cost=1026.09..40270115.62 rows=15001942 width=20)                                       Workers Planned: 4                                       -&gt;  Incremental Sort  (cost=26.03..38482239.64 rows=3750486 width=20)                                             Sort Key: orders.o_custkey, orders.o_orderkey                                             Presorted Key: orders.o_custkey                                             -&gt;  Parallel Index Scan using idx_orders_custkey on orders  (cost=0.43..38380565.22 rows=3750486 width=20)                                 -&gt;  Materialize  (cost=0.56..2715396.56 rows=411897 width=36)                                       -&gt;  Partial GroupAggregate  (cost=0.56..2710119.08 rows=411897 width=36)                                             Group Key: lineitem.l_orderkey                                             -&gt;  Index Scan using idx_lineitem_orderkey on lineitem  (cost=0.56..2405038.67 rows=59986340 width=9)                           -&gt;  Index Scan using customer_pkey on customer  (cost=0.43..75004.52 rows=1500243 width=23)                     -&gt;  Finalize GroupAggregate  (cost=-Infinity..-Infinity rows=1 width=4)                           Group Key: lineitem_1.l_orderkey                           Filter: (sum(lineitem_1.l_quantity) &gt; '314'::numeric)                           -&gt;  Gather Merge  (cost=-Infinity..-Infinity rows=1 width=36)                                 Workers Planned: 4                                 -&gt;  Partial IndexAggregate  (cost=-Infinity..-Infinity rows=0 width=36)                                       Group Key: lineitem_1.l_orderkey                                       -&gt;  Parallel Seq Scan on lineitem lineitem_1  (cost=0.00..1275109.85 rows=14996585 width=9)(30 rows)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u0440\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u0432 \u0433\u043b\u0430\u0437\u0430, &#8212; <code>cost=NaN..NaN<\/code> \u0443 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u0443\u0437\u043b\u0430. \u0415\u0441\u043b\u0438 \u0441\u043f\u0443\u0441\u0442\u0438\u043c\u0441\u044f \u0432\u043d\u0438\u0437, \u0442\u043e \u0434\u043e\u0439\u0434\u0435\u043c \u0434\u043e \u043a\u043e\u0440\u043d\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c &#8212; \u0443\u0437\u0435\u043b Partial IndexAggreate: <code>rows=0<\/code>. \u042d\u0442\u043e\u0433\u043e \u0431\u044b\u0442\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u0430\u0437\u0430 \u043d\u0435 \u043f\u0443\u0441\u0442\u0430\u044f. \u041f\u043e\u0442\u043e\u043c \u044f \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0430 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043b\u0430\u043d\u044b \u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u043b, \u0447\u0442\u043e \u0443 \u0432\u0441\u0435\u0445 \u043f\u043b\u0430\u043d\u043e\u0432 \u0441 Partial IndexAggregate \u043e\u0446\u0435\u043d\u043a\u0430 0. \u042d\u0442\u043e \u0431\u0430\u0433. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e\u0439 &#8212; \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043d\u0435 \u0442\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u0446\u0435\u043d\u043a\u0438 \u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"cpp\">static RelOptInfo *create_partial_grouping_paths(PlannerInfo *root,                              RelOptInfo *grouped_rel,                              RelOptInfo *input_rel,                              grouping_sets_data *gd,                              GroupPathExtraData *extra,                              bool force_rel_creation){   \/* ... *\/    \/*     * Now add a partially-grouped IndexAgg partial Path where possible     *\/    if (can_index &amp;&amp; cheapest_partial_path != NULL)    {        List *pathkeys;        \/* This should have been checked previously *\/        Assert(parse-&gt;hasAggs || parse-&gt;groupClause);          pathkeys = make_pathkeys_for_sortclauses(root,                                                 root-&gt;processed_groupClause,                                                 root-&gt;processed_tlist);        add_partial_path(partially_grouped_rel, (Path *)                          create_agg_path(root,                                    partially_grouped_rel,                                    cheapest_partial_path,                                    partially_grouped_rel-&gt;reltarget,                                    AGG_INDEX,                                    AGGSPLIT_INITIAL_SERIAL,                                    root-&gt;processed_groupClause,                                    NIL,                                    pathkeys,                                    agg_partial_costs,                                    \/* \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c dNumPartialPartialGroups *\/                                    dNumPartialGroups));    }   \/* ... *\/}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043b \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e &#8212; \u0435\u0435 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438.<\/p>\n<p>\u0423 \u043a\u043e\u0433\u043e-\u0442\u043e \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u0442\u0430\u043a \u043f\u043e\u0447\u0435\u043c\u0443 \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u044b\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435? \u0410 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e &#8212; <code>max_parallel_workers_per_gather<\/code> \u0431\u044b\u043b \u043d\u0435 \u043d\u0443\u043b\u0435\u0432\u044b\u043c \u0438 \u0442\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043f\u043b\u0430\u043d \u0441 IndexAggregate \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u0440\u043a\u0435\u0440\u044b, \u0430 \u0432\u0430\u043d\u0438\u043b\u044c\u043d\u044b\u0439 \u043d\u0435\u0442. \u041a\u043e\u0433\u0434\u0430 \u0436\u0435 \u044f \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0431\u0430\u0433\u0430 \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u043b \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0442\u043e \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0441\u0442\u0430\u043b\u0430 \u0445\u0443\u0436\u0435 &#8212; IndexAgg \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435.<\/p>\n<blockquote>\n<p>\u041f\u043b\u0430\u043d\u044b \u0432\u044b\u0448\u0435 \u044f \u043f\u0440\u0438\u0432\u0435\u043b \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438. \u0422\u0435, \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u0441 \u0431\u0430\u0433\u043e\u043c \u0443\u0442\u0435\u0440\u044f\u043d\u044b, \u0430 \u0442.\u043a. \u044f \u0437\u0430 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f \u0442\u0440\u043e\u0433\u0430\u043b \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u0442\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0431\u0430\u0433 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043c\u043e\u0433\u0443, \u0434\u0430\u0436\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043e\u0446\u0435\u043d\u043a\u0438.<\/p>\n<\/blockquote>\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u044d\u0442\u0443 \u043e\u0448\u0438\u0431\u043a\u0443 \u044f \u043d\u0430\u0448\u0435\u043b \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0443\u0441\u043f\u0435\u043b \u0432\u0441\u0435\u043c \u043e \u043d\u0435\u0439 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c.<\/p>\n<\/div>\n<\/details>\n<h4>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/h4>\n<p>\u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0445 \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u044f \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043b. \u0412\u0441\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c Hash\/Group\/Index Agg \u0443\u0437\u043b\u043e\u0432 (\u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u0431\u0435\u0437 \u0447\u0442\u0435\u043d\u0438\u044f \u0441 \u0434\u0438\u0441\u043a\u0430) \u0438 TPC-H. \u041f\u043e \u043f\u0435\u0440\u0432\u043e\u043c\u0443 \u0442\u0435\u0441\u0442\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0435\u0441\u0442\u044c \u0432 <a href=\"https:\/\/www.postgresql.org\/message-id\/e04d5bce-101d-4d70-aa0e-9d1c241cda18%40tantorlabs.ru\">\u044d\u0442\u043e\u043c \u043f\u0438\u0441\u044c\u043c\u0435<\/a>. \u042f \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043b \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c <code>GROUP BY<\/code> \u0441 1 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0422\u0418\u041f x \u0410\u041b\u0413\u041e\u0420\u0418\u0422\u041c x \u0420\u0410\u0417\u041c\u0415\u0420 \u0412\u0425\u041e\u0414\u0410.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#8212; TPS. \u0411\u043e\u043b\u044c\u0448\u0435 &#8212; \u043b\u0443\u0447\u0448\u0435. N\/A &#8212; \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0445\u043e\u0442\u0435\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>int<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">amount<\/p>\n<\/th>\n<th>\n<p align=\"left\">HashAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">GroupAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">IndexAgg<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">100<\/p>\n<\/td>\n<td>\n<p align=\"left\">3249.929602<\/p>\n<\/td>\n<td>\n<p align=\"left\">3501.174072<\/p>\n<\/td>\n<td>\n<p align=\"left\">3765.727121<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1000<\/p>\n<\/td>\n<td>\n<p align=\"left\">504.420643<\/p>\n<\/td>\n<td>\n<p align=\"left\">501.465754<\/p>\n<\/td>\n<td>\n<p align=\"left\">575.255906<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">10000<\/p>\n<\/td>\n<td>\n<p align=\"left\">50.528155<\/p>\n<\/td>\n<td>\n<p align=\"left\">49.312322<\/p>\n<\/td>\n<td>\n<p align=\"left\">54.510261<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">100000<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.775069<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.317584<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.791735<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1000000<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.405538<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.406698<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.321379<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>bigint<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">amount<\/p>\n<\/th>\n<th>\n<p align=\"left\">HashAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">GroupAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">IndexAgg<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">100<\/p>\n<\/td>\n<td>\n<p align=\"left\">3225.287886<\/p>\n<\/td>\n<td>\n<p align=\"left\">3510.612641<\/p>\n<\/td>\n<td>\n<p align=\"left\">3742.911726<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1000<\/p>\n<\/td>\n<td>\n<p align=\"left\">492.908092<\/p>\n<\/td>\n<td>\n<p align=\"left\">491.530184<\/p>\n<\/td>\n<td>\n<p align=\"left\">574.475159<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">10000<\/p>\n<\/td>\n<td>\n<p align=\"left\">50.192018<\/p>\n<\/td>\n<td>\n<p align=\"left\">49.555983<\/p>\n<\/td>\n<td>\n<p align=\"left\">53.909437<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">100000<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.831086<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.430059<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.748821<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1000000<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.401983<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.413218<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.318144<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>text<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">amount<\/p>\n<\/th>\n<th>\n<p align=\"left\">HashAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">GroupAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">IndexAgg<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">100<\/p>\n<\/td>\n<td>\n<p align=\"left\">2647.030876<\/p>\n<\/td>\n<td>\n<p align=\"left\">2553.503954<\/p>\n<\/td>\n<td>\n<p align=\"left\">2946.282525<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1000<\/p>\n<\/td>\n<td>\n<p align=\"left\">348.464373<\/p>\n<\/td>\n<td>\n<p align=\"left\">286.818555<\/p>\n<\/td>\n<td>\n<p align=\"left\">342.771923<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">10000<\/p>\n<\/td>\n<td>\n<p align=\"left\">32.891834<\/p>\n<\/td>\n<td>\n<p align=\"left\">24.386304<\/p>\n<\/td>\n<td>\n<p align=\"left\">28.249571<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">100000<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.934513<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.956983<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.237997<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1000000<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.249291<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.148780<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.150943<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>uuid<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">amount<\/p>\n<\/th>\n<th>\n<p align=\"left\">HashAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">GroupAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">IndexAgg<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">100<\/p>\n<\/td>\n<td>\n<p align=\"left\">N\/A<\/p>\n<\/td>\n<td>\n<p align=\"left\">2282.812585<\/p>\n<\/td>\n<td>\n<p align=\"left\">2432.713816<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1000<\/p>\n<\/td>\n<td>\n<p align=\"left\">N\/A<\/p>\n<\/td>\n<td>\n<p align=\"left\">282.637163<\/p>\n<\/td>\n<td>\n<p align=\"left\">303.892131<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">10000<\/p>\n<\/td>\n<td>\n<p align=\"left\">N\/A<\/p>\n<\/td>\n<td>\n<p align=\"left\">28.375838<\/p>\n<\/td>\n<td>\n<p align=\"left\">28.924711<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">100000<\/p>\n<\/td>\n<td>\n<p align=\"left\">N\/A<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.649958<\/p>\n<\/td>\n<td>\n<p align=\"left\">2.449907<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">1000000<\/p>\n<\/td>\n<td>\n<p align=\"left\">N\/A<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.255203<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.194414<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>bigtext (\u0434\u043b\u0438\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438)<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">HashAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">GroupAgg<\/p>\n<\/th>\n<th>\n<p align=\"left\">IndexAgg<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">N\/A<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.035247<\/p>\n<\/td>\n<td>\n<p align=\"left\">0.041120<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/details>\n<p>\u0412\u044b\u0432\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439: \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u043e, \u043d\u043e \u043d\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0441\u0430\u043c\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u0432\u0435\u043b\u0438\u043a\u043e (\u043f\u0430\u0440\u0430 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043e\u0432).<\/p>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u0442\u0435\u0441\u0442 &#8212; TPC-H. \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442. \u0412\u0441\u0435\u0433\u043e \u0432 \u044d\u0442\u043e\u043c \u043d\u0430\u0431\u043e\u0440\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e 22 \u0442\u0435\u0441\u0442\u0430, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u043e\u043b\u044c\u043a\u043e 8 \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e (\u043f\u0440\u0438\u0447\u0435\u043c \u043d\u0435 \u0432\u0435\u0437\u0434\u0435), \u0430 \u0441\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0438\u0439 &#8212; \u0432 \u043e\u0434\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u0440\u043e\u0441\u0442, \u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043d\u0435\u0442, \u0434\u0430 \u0438 \u0441\u0430\u043c\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u043e\u0433\u0440\u0435\u0448\u043d\u043e\u0441\u0442\u0438 (\u043f\u0430\u0440\u0430 \u043c\u0441).<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c TPC-H<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#8212; \u043c\u0441 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438. \u041c\u0435\u043d\u044c\u0448\u0435 &#8212; \u043b\u0443\u0447\u0448\u0435. \u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 IndexAgg.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0437\u0430\u043f\u0440\u043e\u0441<\/p>\n<\/th>\n<th>\n<p align=\"left\">Vanilla<\/p>\n<\/th>\n<th>\n<p align=\"left\">IndexAgg<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">4<\/p>\n<\/td>\n<td>\n<p align=\"left\">1023.309<\/p>\n<\/td>\n<td>\n<p align=\"left\">1016.593<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">5<\/p>\n<\/td>\n<td>\n<p align=\"left\">3811.967<\/p>\n<\/td>\n<td>\n<p align=\"left\">3815.733<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">7<\/p>\n<\/td>\n<td>\n<p align=\"left\">3904.189<\/p>\n<\/td>\n<td>\n<p align=\"left\">3901.531<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">8<\/p>\n<\/td>\n<td>\n<p align=\"left\">2474.345<\/p>\n<\/td>\n<td>\n<p align=\"left\">2469.738<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">10<\/p>\n<\/td>\n<td>\n<p align=\"left\">4740.509<\/p>\n<\/td>\n<td>\n<p align=\"left\">4563.427<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">12<\/p>\n<\/td>\n<td>\n<p align=\"left\">6128.857<\/p>\n<\/td>\n<td>\n<p align=\"left\">6142.829<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">21<\/p>\n<\/td>\n<td>\n<p align=\"left\">4920.473<\/p>\n<\/td>\n<td>\n<p align=\"left\">5001.543<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">22<\/p>\n<\/td>\n<td>\n<p align=\"left\">652.161<\/p>\n<\/td>\n<td>\n<p align=\"left\">651.856<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/details>\n<p>\u0412 \u043e\u0434\u0438\u043d \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c B+tree \u043d\u0430 T-tree, \u043d\u043e \u044d\u0442\u043e \u043f\u0440\u0438\u0440\u043e\u0441\u0442\u0430 \u043d\u0435 \u0434\u0430\u043b\u043e, \u0430 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u0441\u043d\u0438\u0437\u0438\u043b\u043e. \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043f\u0430\u0442\u0447\u0435\u043c \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0442\u0435\u0441\u0442\u0430 <a href=\"https:\/\/www.postgresql.org\/message-id\/f41ddd0f-25ba-4b02-af6b-23a44f4164d8%40tantorlabs.ru\">\u0442\u0443\u0442<\/a>.<\/p>\n<h4>\u041f\u043e\u0434\u044b\u0442\u043e\u0436\u0438\u043c<\/h4>\n<ul>\n<li>\n<p>\u041c\u043e\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u043e\u0431\u0449\u0435\u0433\u043e \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0434\u0435\u044e, \u0442.\u043a. \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u044f \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u043b \u043f\u043e\u0434 \u0441\u0435\u0431\u044f<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043c\u0430\u043b\u043e\u0437\u0430\u043c\u0435\u0442\u043d\u0430<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0442\u0440\u043e\u043d\u0443\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430 (\u0434\u0438\u0444\u0444 \u043f\u0430\u0442\u0447\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u0439)<\/p>\n<\/li>\n<\/ul>\n<p>\u042f \u0441\u0447\u0438\u0442\u0430\u044e, \u0447\u0442\u043e \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u043c &#8212; \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0446\u0435\u043d\u0430 \u0437\u0430 \u0442\u0430\u043a\u043e\u0439 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u043f\u0440\u043e\u0444\u0438\u0442. \u0421\u043a\u043e\u0440\u0435\u0435, \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u043e\u0448\u0435\u043b \u043e\u0442 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438 \u043d\u0435 \u0441\u0442\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e\u0435 B+tree \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0431\u043e\u0440 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u0441\u043b\u0438\u044f\u043d\u0438\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430, \u0430 \u043d\u0435 \u0434\u0435\u0440\u0435\u0432\u0430 \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0432\u0448\u0438\u0445 (tree of losers)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0441\u043b\u0438\u044f\u043d\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0437\u0430 1 \u043f\u0440\u043e\u0445\u043e\u0434 (Wide Merge)<\/p>\n<\/li>\n<\/ul>\n<blockquote>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043f\u043e\u043a\u0430 \u043f\u0438\u0441\u0430\u043b \u0441\u0432\u043e\u0439 \u043f\u0430\u0442\u0447 \u0432 \u0445\u0430\u043a\u0435\u0440\u0441\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0438 \u043f\u0430\u0442\u0447, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430 \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0432\u0448\u0438\u0445 \u0434\u043b\u044f \u0441\u043b\u0438\u044f\u043d\u0438\u044f &#8212; <a href=\"https:\/\/www.postgresql.org\/message-id\/tencent_901D6A0152786410F0E00E72EC38432D0A09%40qq.com\">\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435<\/a>.<\/p>\n<\/blockquote>\n<p>\u041d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u0434\u0432\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u043b\u043e\u0433\u0438\u043a\u0443 \u0441\u0431\u0440\u043e\u0441\u0430 (\u0430 \u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0431\u0435\u0437 \u043d\u0435\u0435), \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0443\u0445\u0443\u0434\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u044d\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0441\u0430\u043c\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u043d\u0430 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043d\u043e\u0442\u0435. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435 <code>GROUP BY<\/code>, \u0430 \u0441\u0430\u043c\u0430 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430. \u042d\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0449\u044c, \u0442.\u043a. \u0441\u0430\u043c\u0430 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445: <code>DISTINCT<\/code> \u0438 <code>UNION<\/code>. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u0438 \u043e\u043a\u043e\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u044b. \u0412 \u043e\u0431\u0449\u0435\u043c \u0438 \u0446\u0435\u043b\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438 \u0432 PostgreSQL, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 <code>GROUP BY<\/code>.<\/p>\n<p>\u0421\u0430\u043c\u0430 \u0438\u0434\u0435\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 (\u0438 \u0434\u043e\u043a\u043b\u0430\u0434\u0430) \u0440\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u043f\u043e \u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435, \u0447\u0442\u043e \u044f \u043d\u0438\u0433\u0434\u0435 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 (\u043c\u043e\u0434\u0443\u043b\u044f <code>nodeAgg.c<\/code>). \u041a\u043e\u043d\u0435\u0447\u043d\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u043a\u043e\u0434\u0435, \u043d\u043e \u0438\u0445 \u0431\u044b\u043b\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u201c\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0438 \u043f\u043e\u043d\u044f\u0442\u044c\u201d. \u041a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f, \u0434\u0443\u043c\u0430\u0442\u044c \u0438 \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f. \u041f\u043e \u044d\u0442\u043e\u0439 \u0436\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0437\u0434\u0435\u0441\u044c \u044f \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u0445\u043e\u0434\u0438\u043b \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u0442.\u043a. \u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044f \u0443\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043b, \u0434\u043e\u043b\u0436\u043d\u043e \u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0441 \u0433\u043e\u043b\u043e\u0432\u043e\u0439.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1031592\/\">https:\/\/habr.com\/ru\/articles\/1031592\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e.\u0418\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0440\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0435 \u0432 PostgreSQL. \u0410\u0434\u043c\u0438\u043d\u044b \u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u043f\u043e\u0434\u0443\u043c\u0430\u044e\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u044f \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e \u0432\u0441\u044f\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432, \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0411\u0443\u0434\u0443. \u0422\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437 \u043f\u043e\u0439\u0434\u0435\u0442 \u043d\u0435 \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0430 \u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.\u0415\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0431\u044c\u0435\u0442\u0435 \u0432 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a\u0435 \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u201c\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 postgresql\u201d, \u0442\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c, \u043d\u0430 \u0447\u0442\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c, &#8212; \u044d\u0442\u043e CREATE AGGREGATE \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0438\/\u0438\u043b\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u201c\u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0433\u043e\u201d GROUP BY GROUPING SETS. \u041d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0438 \u0441\u043b\u043e\u0432\u0430 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430.\u041c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u0434\u043e\u043c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 (\u0437\u0430\u0447\u0435\u043c &#8212; \u0432 \u043a\u043e\u043d\u0446\u0435). \u041a\u043e\u0433\u0434\u0430 \u0434\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u0437\u0430\u0434\u0430\u0447\u0443, \u0441\u0430\u043c\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u044f \u0432\u044b\u0434\u0435\u043b\u0438\u043b \u043b\u043e\u0433\u0438\u043a\u0443 \u0441\u0431\u0440\u043e\u0441\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a. \u041d\u043e \u043f\u043e\u0442\u043e\u043c \u0432\u044b\u0448\u043b\u043e, \u0447\u0442\u043e \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u0441\u0430\u043c\u043e\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0435 &#8212; \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043c\u043e\u0434\u0443\u043b\u044c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c.\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u043c\u043e\u0435\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u043d\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 PG BootCamp (YouTube\/RuTube). \u0418\u0437-\u0437\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043c\u043d\u043e\u0433\u043e\u0435 \u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u201c\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0439\u201d \u0432\u0435\u0440\u0441\u0438\u0435\u0439. \u0412 \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u043e \u044f\u0434\u0440\u043e \u0438 \u0432\u044b\u043d\u0435\u0441 \u0437\u0430 \u0441\u043a\u043e\u0431\u043a\u0438 \u0432\u0441\u0435, \u0447\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043d\u0435\u0432\u0430\u0436\u043d\u044b\u043c. \u0417\u0434\u0435\u0441\u044c \u044d\u0442\u043e \u0432\u0441\u0435 \u0435\u0441\u0442\u044c.\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435:\u0410\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438\u041f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c \u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430\u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0441\u0431\u0440\u043e\u0441 \u043d\u0430 \u0434\u0438\u0441\u043aGROUPING SETS \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430\u0421\u043c\u0435\u0448\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f\u041e\u0441\u0442\u0430\u0432\u0448\u0435\u0435\u0441\u044f \u0437\u0430 \u043a\u0430\u0434\u0440\u043e\u043c \u0427\u0430\u0441\u0442\u0438\u0447\u043d\u0430\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044fORDERED SET AGGREGATEIndex Aggregate\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u0410\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438\u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f. \u042d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0449\u0430\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u0442\u044c 2 \u044f\u0440\u043a\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430: max &#8212; \u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0438 avg &#8212; \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435.&#8212; \u0421\u0430\u043c\u044b\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0438 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439SELECT max(age) FROM users;&#8212; \u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044fSELECT userid, avg(transferred) FROM user_transactions GROUP BY userid;\u0427\u0442\u043e\u0431\u044b \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c max, \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0447\u0438\u0441\u043b\u043e &#8212; \u0441\u0430\u043c\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, &#8212; \u0438 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435\u0435. \u0410 \u0432\u043e\u0442 \u0434\u043b\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0430\u0441\u0447\u0435\u0442\u0430 avg \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0443\u0436\u0435 \u0434\u0432\u0430 \u0447\u0438\u0441\u043b\u0430 &#8212; \u0441\u0443\u043c\u043c\u0443 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u0443\u043c\u043c\u0443 \u043d\u0430 \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e, \u0430 \u043f\u0435\u0440\u0435\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0434\u0435\u043b\u0438\u043c \u0441\u0443\u043c\u043c\u0443 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e.\u0412\u044b\u0445\u043e\u0434\u0438\u0442, \u0447\u0442\u043e \u0443 \u0440\u0430\u0437\u043d\u044b\u0445 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u0440\u0430\u0437\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0437\u043e\u043e\u043f\u0430\u0440\u043a, \u0431\u044b\u043b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u043c\u0438.\u0412\u043e\u043e\u0431\u0449\u0435, \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u201c\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430\u201d \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 &#8212; \u044d\u0442\u043e \u043c\u043e\u0435 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u0443\u043c\u0435\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u044e \u044d\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443.\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:# \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044fstate = init()# \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430for tuple in input:   state = transit(state, tuple)# \u041f\u043e\u0434\u0441\u0447\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430result = finalize(state)\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e CREATE AGGREGATE \u044d\u0442\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u043c\u044b \u0438 \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c:CREATE AGGREGATE some_agg(a int, b int) (   &#8212; \u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435   initcond  = &#8216;(0,0)&#8217;   &#8212; \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430   sfunc     = average_transition,   &#8212; \u0424\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440   finalfunc = average_final,   &#8212; &#8230;)\u0412\u0441\u0435 \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 pg_aggregate. \u0415\u0441\u0442\u044c \u0443\u0436\u0435 \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432, \u043d\u043e \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u044b\u0448\u0435:select aggfnoid, agginitval, aggtransfn, aggfinalfn from pg_aggregate;         aggfnoid       |    agginitval   |    aggtransfn    |      aggfinalfn        &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; pg_catalog.stddev      | {0,0,0}         | float4_accum     | float8_stddev_samp pg_catalog.avg         | {0,0,0}         | float4_accum     | float8_avg pg_catalog.avg         | {0,0}           | int4_avg_accum   | int8_avg pg_catalog.max         |                 | int4larger       | &#8212; pg_catalog.max         |                 | float4larger     | &#8212;  &#8230;\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b (\u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u043b\u044f int4):avg &#8212; \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 &#8212; \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0434\u0432\u0443\u0445 \u043d\u0443\u043b\u0435\u0439 (\u0441\u0443\u043c\u043c\u0430 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e), \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 int4_avg_accum &#8212; \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0443\u043c\u043c\u0443 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e, \u0430 int8_avg \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 &#8212; \u0434\u0435\u043b\u0438\u0442 \u0438\u0445. \u0414\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f avg &#8212; \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0447\u0438\u0441\u0435\u043b, \u0430 \u043d\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441 \u0434\u0432\u0443\u043c\u044f \u043f\u043e\u043b\u044f\u043c\u0438. \u041f\u043e\u0434\u043e\u0431\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u0438\u0435 \u0442\u0438\u043f\u044b, \u0442.\u043a. \u0442\u0438\u043f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0430 \u0435\u0441\u043b\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f, \u0442\u043e \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u0431\u0443\u0445\u043d\u0435\u0442.max &#8212; \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 int4larger, \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043d\u0435\u0442 (NULL) \u0438 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0442\u043e\u0436\u0435.\u0415\u0441\u043b\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 NULL &#8212; \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u043e\u0435 \u043d\u0435 NULL \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f. \u0410 \u0435\u0441\u043b\u0438 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u043d\u0435\u0442, \u0442\u043e \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0435\u0441\u0442\u044c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 max \u0432\u0441\u0435 \u044d\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442: \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e, \u0430 \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u0430\u043c\u043e \u0447\u0438\u0441\u043b\u043e \u0438 \u0435\u0441\u0442\u044c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0442\u043e \u0438 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e.\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f avg \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043c\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:state = {0, 0}for number in input:   state.count++   state.sum += numberresult = state.sum \/ state.count\u0410 \u0434\u043b\u044f max \u0442\u0430\u043a:state = NULLfor number in input:   if state == NULL or state &lt; number:      state = numberresult = state\u041d\u043e \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a, \u0430 \u043f\u0440\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0435. \u0421\u0430\u043c\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 &#8212; \u043f\u043b\u043e\u0441\u043a\u0430\u044f.\u041f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430SELECT avg(a) FROM tbl;       QUERY PLAN&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; Aggregate   -&gt;  Seq Scan on tbl(2 rows)\u0413\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 &#8212; \u044d\u0442\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044f \u043f\u043e \u0432\u0441\u0435\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c.\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u044e \u201c\u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 &#8212; \u044d\u0442\u043e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0431\u0435\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432\u201d, \u0442.\u043a. \u0442\u0430\u0432\u0442\u043e\u043b\u043e\u0433\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f()\u041c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u0442 GROUP BY, \u043d\u043e \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0434\u0430 \u043b\u0438\u0448\u044c \u043e\u0442\u0447\u0430\u0441\u0442\u0438, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0435\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 (), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u043b\u043e\u0441\u043a\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:SELECT avg(a) FROM tbl GROUP BY ();\u0418 \u043f\u043b\u0430\u043d \u0431\u0443\u0434\u0435\u0442 \u0442\u0435\u043c \u0436\u0435.\u0412 \u0441\u0430\u043c\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 SQL (ISO\/IEC 9075, Part 2, 7.13) \u043a \u043d\u0435\u043c\u0443 \u0441\u0441\u044b\u043b\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a &lt;empty grouping set&gt;.\u041e\u0431 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043a\u043e\u0434\u0443.\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 src\/backend\/executor\/nodeAgg.c \u0438, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043e\u0433\u043e\u0432\u043e\u0440\u0435\u043d\u043e \u0438\u043d\u043e\u0435, \u0432\u0435\u0441\u044c \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0442\u0430\u043c. \u0414\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0441\u0442\u0438, \u0432\u0435\u0441\u044c \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u044f \u0431\u0443\u0434\u0443 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0435\u043c.PostgreSQL \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 &#8212; \u0437\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u043f\u043b\u0430\u043d\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u041e\u043d \u0447\u0438\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438\u0437 \u043f\u043e\u0434\u0443\u0437\u043b\u0430, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u043e\u0440\u0442\u0435\u0436\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0435\u043c\u0443 (\u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u0443\u0437\u043b\u0443).ExecAgg\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2244 *\/static TupleTableSlot *ExecAgg(PlanState *pstate){    AggState   *node = castNode(AggState, pstate);    TupleTableSlot *result = NULL;    if (!node-&gt;agg_done)    {        \/* Dispatch based on strategy *\/        switch (node-&gt;aggstrategy)        {            case AGG_HASHED:                \/* &#8230; *\/            case AGG_MIXED:                \/* &#8230; *\/            case AGG_PLAIN:                \/* &#8230; *\/            case AGG_SORTED:               return agg_retrieve_direct(node);        }    }    return NULL;}\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0443\u0437\u043b\u0430 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f ExecAgg, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 &#8212; \u043f\u0440\u043e\u0441\u0442\u043e\u0439 switch, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u043d\u0443\u0436\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e. \u0414\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439, \u044d\u0442\u043e \u043d\u0435 \u0441\u0435\u043a\u0440\u0435\u0442. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u043f\u043b\u043e\u0441\u043a\u0443\u044e \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443, \u0438 \u0437\u0430 \u043d\u0435\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 AGG_PLAIN, \u0441\u0430\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a &#8212; agg_retrieve_direct.agg_retrieve_direct\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/backend\/executor\/nodeAgg.c#L2280 *\/static TupleTableSlot *agg_retrieve_direct(AggState *aggstate){   Agg           *node = aggstate-&gt;phase-&gt;aggnode;   AggStatePerAgg peragg;   AggStatePerGroup *pergroups;   \/* \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 *\/   outerslot = fetch_input_tuple(aggstate);   \/* \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f *\/   initialize_aggregates(aggstate, pergroups, numReset);   \/* \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0438\u0437 \u0432\u0445\u043e\u0434\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 *\/   for (;;)   {      advance_aggregates(aggstate);      outerslot = fetch_input_tuple(aggstate);      if (TupIsNull(outerslot))      {         aggstate-&gt;agg_done = true;         break;      }   }   \/* \u0412\u044b\u0437\u043e\u0432 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 *\/   finalize_aggregates(aggstate, peragg, pergroups[currentSet]);      return project_aggregates(aggstate);}\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 1-\u043a-1 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 (\u0435\u0433\u043e \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434) \u0432\u044b\u0448\u0435. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u043a\u043e\u0440\u0442\u0435\u0436 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0432\u0445\u043e\u0434 \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0439, \u0430 \u0437\u0430\u0447\u0435\u043c \u0438\u043c\u0435\u043d\u043d\u043e &#8212; \u0443\u0432\u0438\u0434\u0438\u043c \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435.\u0414\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439 \u0438\u0437 \u043f\u043e\u0434\u0443\u0437\u043b\u0430 \u0432 \u044d\u0442\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f fetch_input_tuple. \u041f\u043e\u043a\u0430 \u043d\u0430\u043c \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438, \u0438 \u0447\u0438\u0442\u0430\u0435\u043c \u0432\u0441\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0438\u0437 \u043f\u043e\u0434-\u0443\u0437\u043b\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, SeqScan.\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c, \u043d\u0443\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f initialize_aggregates. \u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438.\/* https:\/\/github.com\/postgres\/postgres\/blob\/REL_18_3\/src\/include\/executor\/nodeAgg.h#L250 *\/struct AggStatePerGroupData{    Datum  transValue;        \/* current transition value *\/    bool   transValueIsNull;    bool   noTransValue;      \/* true if transValue not set yet *\/};\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 AggStatePerGroup \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0430\u043c\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430. \u041e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438.\u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u0434\u0432\u0430 \u043f\u043e\u043b\u044f: \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 NULL, \u043d\u043e \u0435\u0441\u0442\u044c \u0438 \u0442\u0440\u0435\u0442\u0438\u0439 &#8212; \u0444\u043b\u0430\u0433 noTransValue. \u0414\u0435\u043b\u043e \u0432 \u043d\u044e\u0430\u043d\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 NULL\u2019\u0430\u043c\u0438, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b \u0440\u0430\u043d\u0435\u0435, &#8212; \u0435\u0441\u043b\u0438 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 NULL, \u0442\u043e \u043f\u0435\u0440\u0432\u043e\u0435 \u043d\u0435 NULL \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c, \u043d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0444\u043b\u0430\u0433 &#8212; \u043a\u0430\u043a \u0442\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0442\u044c NULL, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435, \u043e\u0442 NULL, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0440\u043d\u0443\u043b\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u043b\u0430\u0433.\u041d\u043e \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0430 \u0441\u0430\u043c\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0434\u0432\u0443\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u0445 &#8212; AggStatePerTrans \u0438 AggStatePerAgg.\u0412\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u044c PerTrans \u0438 PerAgg \u0441 \u043b\u043e\u0433\u0438\u043a\u043e\u0439\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0432\u0435\u043b\u0438\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0445 \u043f\u043e\u043b\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u044f \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0436\u0443, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043b\u044f. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0432\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 PerTrans \u0438 \u043d\u0430 PerAgg.AggStatePerTrans \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430, \u043d\u043e \u0432\u043e\u0442 \u0444\u0438\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 &#8212; AggStatePerAgg. \u0421\u0434\u0435\u043b\u0430\u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a, \u0430 \u0432 \u0443\u0433\u043e\u0434\u0443 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438.SELECT agginitval, aggtransfn, count(*) cnt FROM&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-478614","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/478614","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=478614"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/478614\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=478614"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=478614"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=478614"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}