{"id":378369,"date":"2024-06-09T03:00:06","date_gmt":"2024-06-09T03:00:06","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=378369"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=378369","title":{"rendered":"<span>\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0440\u043e\u0448\u0438 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0438 btree_gist \u0438\u043d\u0434\u0435\u043a\u0441 \u0432 PostgreSQL<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 PostgreSQL \u0435\u0441\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b &#8212;  \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 (range). \u041e\u043d\u0438 \u0432\u0435\u0441\u044c\u043c\u0430 \u0443\u0434\u043e\u0431\u043d\u044b \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438. \u0414\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 GIST \u0438\u043d\u0434\u0435\u043a\u0441. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0447\u0430\u0441\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 BTREE \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0441 GIST, \u0447\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c <a href=\"https:\/\/www.postgresql.org\/docs\/current\/btree-gist.html\" rel=\"noopener noreferrer nofollow\">btree_gist<\/a>. \u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0435 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 btree_gist \u043c\u044b \u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p>\u0414\u043b\u044f \u041b\u041b &#8212; \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 btree_gist \u0431\u0443\u0434\u0435\u0442 \u043f\u043b\u043e\u0445\u043e.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043f\u043e \u0434\u0430\u0442\u0430\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0430. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0438 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0434\u0430\u0442, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u0438 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0431\u044b\u043b\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"center\">\u041a\u043b\u0438\u0435\u043d\u0442<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0414\u0430\u0442\u0430 \u0441<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0414\u0430\u0442\u0430 \u043f\u043e<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0424\u0430\u043c\u0438\u043b\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0422\u0435\u043b\u0435\u0444\u043e\u043d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">2020-01-01<\/p>\n<\/td>\n<td>\n<p align=\"left\">2020-07-12<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0432\u0430\u043d\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">+74991001010<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">2021-05-20<\/p>\n<\/td>\n<td>\n<p align=\"left\">2023-02-28<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0442\u0440\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">+74991001010<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">2023-03-01<\/p>\n<\/td>\n<td>\n<p align=\"left\">2023-09-11<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0442\u0440\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">+74959990101<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">2023-12-22<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0438\u0434\u043e\u0440\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">+74959990101<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0443\u0441\u0442\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#171;\u0414\u0430\u0442\u0430 \u043f\u043e&#187; \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 &#171;\u0414\u0430\u0442\u044b \u0441&#187; \u0434\u043e \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0441\u0442\u0438. \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0442\u044c\u0441\u044f, \u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430\u043c\u0438 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u044b\u0432\u044b \u043d\u0430 \u0442\u043e \u0432\u0440\u0435\u043c\u044f, \u043f\u043e\u043a\u0430 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 \u043d\u0435 \u0431\u044b\u043b\u043e. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0440\u0430\u0437\u0440\u044b\u0432\u044b \u043c\u0435\u0436\u0434\u0443 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430\u043c\u0438 \u043c\u044b \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e GIST \u0438\u043d\u0434\u0435\u043a\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432, \u043d\u043e \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0440\u0430\u0437\u0440\u044b\u0432\u043e\u0432. \u0410 \u0442\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0437\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435\u043c \u0440\u0430\u0437\u0440\u044b\u0432\u043e\u0432 \u0431\u0435\u0437 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u0442\u043e \u0434\u043b\u044f \u0446\u0435\u043b\u0435\u0439 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 BTREE \u0438 btree_gist \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442.<\/p>\n<p>\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0434\u0435\u043b\u0430\u0432 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (Id) \u043f\u0440\u043e\u0441\u0442\u043e integer, \u0430 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u0443\u0441\u0442\u044c \u0431\u0443\u0434\u0443\u0442 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0438 \u0447\u0438\u0441\u043b\u043e\u043c. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE tmp_test_range (   Id    integer       NOT NULL,   Valid daterange     NOT NULL, -- \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0434\u0430\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430   Code  integer       NOT NULL,   Amt   decimal(16,2) NOT NULL,   CONSTRAINT tmp_test_range_PK_idx     EXCLUDE USING GIST (Id WITH =, Valid WITH &amp;&amp;) -- \u0437\u0430\u043f\u0440\u0435\u0442 \u043d\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435  );<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u043d\u0430\u0448\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<pre><code class=\"pgsql\">INSERT INTO tmp_test_range (Id, Valid, Code, Amt) SELECT G.n \/ 10 AS Id,   daterange(     ( '2023-01-01'::date       + '1 day'::interval       * (G.n % 10) * 30 )::date,     CASE WHEN G.n % 10 = 9 THEN NULL       ELSE         ( '2023-01-01'::date           + '1 day'::interval           * ( (G.n % 10) * 30                + (G.n % 10 + 1) * 3 ) )::date END,     '[)' ),   G.n AS Code,   G.n*0.5 AS Amt FROM generate_series(0,999999) G(n);<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041d\u0430 \u043c\u043e\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 PostgreSQL 15 \u044d\u0442\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 45 \u0441\u0435\u043a\u0443\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">Insert on tmp_test_range  (cost=0.00..67500.00 rows=0 width=0) (actual time=45364.169..45364.170 rows=0 loops=1)   ->  Function Scan on generate_series g  (cost=0.00..67500.00 rows=1000000 width=58) (actual time=63.500..1115.834 rows=1000000 loops=1) Planning Time: 0.068 ms Execution Time: 45373.995 ms<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f btree_gist \u0438 GIST. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE tmp_test_not_range (   Id         integer       NOT NULL,   ValidFrom  date          NOT NULL,   ValidUntil date          NULL,   Code       integer       NOT NULL,   Amt        decimal(16,2) NOT NULL,   CONSTRAINT tmp_test_not_range_PK_idx     PRIMARY KEY (Id, ValidFrom) INCLUDE (ValidUntil) );<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432 \u0434\u0430\u0442 BTREE \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442, \u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044d\u0442\u043e \u0441\u0430\u043c\u0438\u043c \u0447\u0435\u0440\u0435\u0437 \u0442\u0440\u0438\u0433\u0433\u0435\u0440. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430:<\/p>\n<pre><code class=\"pgsql\">CREATE OR REPLACE FUNCTION   tmp_test_not_range_before_insert_update_tfn() RETURNS TRIGGER AS $func$ &lt;&lt;func>> DECLARE   ValidFrom  date;   ValidUntil date; BEGIN   -- \u0414\u0430\u0442\u0430 \u043a\u043e\u043d\u0446\u0430 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043b\u0438 \u0440\u0430\u0432\u043d\u0430 \u0434\u0430\u0442\u0435 \u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430   IF NEW.ValidFrom>COALESCE(NEW.ValidUntil,NEW.ValidFrom) THEN     RAISE EXCEPTION 'ValidUntil must be higher or equal ValidFrom';   END IF;    -- \u0418\u0449\u0435\u043c, \u043d\u0435\u0442 \u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432   -- \u041f\u0440\u0438 UPDATE \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0438\u0437 \u043f\u043e\u0438\u0441\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c   SELECT F.ValidFrom, F.ValidUntil   FROM (     SELECT T.ValidFrom, T.ValidUntil      FROM tmp_test_not_range T     WHERE T.Id=NEW.Id       AND ( OLD.Id IS NULL         OR NOT (T.Id=OLD.Id AND T.ValidFrom=OLD.ValidFrom) )     AND T.ValidFrom&lt;=COALESCE(NEW.ValidUntil,'infinity'::date)     ORDER BY T.ValidFrom DESC     LIMIT 1 ) F   WHERE COALESCE(F.ValidUntil,'infinity'::date)>=NEW.ValidFrom   INTO func.ValidFrom, func.ValidUntil;    -- \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e, \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438   IF func.ValidFrom IS NOT NULL THEN     RAISE EXCEPTION       'Id % ValidFrom % intersect with ValidFrom % and ValidUntil %',       NEW.Id, New.ValidFrom, func.ValidFrom, func.ValidUntil;   END IF;    RETURN NEW; END; $func$ LANGUAGE plpgsql;<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u0442\u0440\u0438\u0433\u0433\u0435\u0440:<\/p>\n<pre><code class=\"pgsql\">CREATE OR REPLACE TRIGGER tmp_test_not_range_before_insert_update_trg   BEFORE INSERT OR UPDATE OF Id, ValidFrom, ValidUntil   ON tmp_test_not_range FOR EACH ROW   EXECUTE FUNCTION tmp_test_not_range_before_insert_update_tfn();<\/code><\/pre>\n<p>\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0438 \u044d\u0442\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0442\u0435\u043c\u0438 \u0436\u0435 \u0441\u0430\u043c\u044b\u043c\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438:<\/p>\n<pre><code class=\"pgsql\">INSERT INTO tmp_test_not_range (Id,   ValidFrom, ValidUntil, Code, Amt) SELECT G.n \/ 10 AS Id,   ( '2023-01-01'::date     + '1 day'::interval     * (G.n % 10) * 30 )::date,   CASE WHEN G.n % 10 = 9 THEN NULL     ELSE       ( '2023-01-01'::date         + '1 day'::interval         * ( (G.n % 10) * 30              + (G.n % 10 + 1) * 3 ) )::date END,   G.n AS Code,   G.n*0.5 AS Amt FROM generate_series(0,999999) G(n);<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041d\u0430 \u043c\u043e\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 PostgreSQL 15 \u044d\u0442\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0435\u043d\u0435\u0435 12 \u0441\u0435\u043a\u0443\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">Insert on tmp_test_not_range  (cost=0.00..65000.00 rows=0 width=0) (actual time=11581.151..11581.151 rows=0 loops=1)   ->  Function Scan on generate_series g  (cost=0.00..65000.00 rows=1000000 width=34) (actual time=83.449..890.624 rows=1000000 loops=1) Planning Time: 0.086 ms Trigger tmp_test_not_range_after_insert_update_trg: time=8429.938 calls=1000000 Execution Time: 11621.851 ms<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0442\u0430\u0432\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e btree_gist \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0447\u0442\u0438 \u0432 4 \u0440\u0430\u0437\u0430 \u0432\u0441\u0442\u0430\u0432\u043a\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e BTREE \u043f\u043b\u044e\u0441 \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0430 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0435.<\/p>\n<p>\u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c btree_gist \u0434\u0430\u0441\u0442 \u0432\u044b\u0438\u0433\u0440\u044b\u0448 \u0445\u043e\u0442\u044f \u0431\u044b \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445? \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c. \u0412\u044b\u0431\u0435\u0440\u0435\u043c \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u043c \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438 100 \u0442\u044b\u0441. \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 Id \u0432\u0441\u0435\u0433\u043e 10 \u0442\u044b\u0441 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 Id \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u0430\u0442\u0443:<\/p>\n<pre><code class=\"pgsql\">SELECT R.Id, R.Valid, R.Code, R.Amt FROM generate_series(0,999999,10) G(n) JOIN tmp_test_range R ON R.Id=G.n AND R.Valid@>'2023-06-12'::date;<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0423 \u043c\u0435\u043d\u044f \u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f 180 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">Hash Join  (cost=11992.91..20109.38 rows=99147 width=28) (actual time=155.387..179.831 rows=10000 loops=1)   Hash Cond: (g.n = r.id)   ->  Function Scan on generate_series g  (cost=0.00..1000.00 rows=100000 width=4) (actual time=7.546..11.391 rows=100000 loops=1)   ->  Hash  (cost=10753.36..10753.36 rows=99164 width=28) (actual time=147.726..147.729 rows=100000 loops=1)         Buckets: 131072  Batches: 1  Memory Usage: 7368kB         ->  Bitmap Heap Scan on tmp_test_range r  (cost=1769.81..10753.36 rows=99164 width=28) (actual time=106.657..132.703 rows=100000 loops=1)               Recheck Cond: (valid @> '2023-06-12'::date)               Heap Blocks: exact=7744               ->  Bitmap Index Scan on tmp_test_range_pk_idx  (cost=0.00..1745.02 rows=99164 width=0) (actual time=105.592..105.592 rows=100000 loops=1)                     Index Cond: (valid @> '2023-06-12'::date) Planning Time: 0.179 ms Execution Time: 180.755 ms<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435:<\/p>\n<pre><code class=\"pgsql\">SELECT R.Id, R.ValidFrom, R.ValidUntil, R.Code, R.Amt FROM generate_series(0,999999,10) G(n) CROSS JOIN LATERAL (   SELECT T.Id, T.ValidFrom, T.ValidUntil, T.Code, T.Amt   FROM tmp_test_not_range T   WHERE T.Id=G.n AND T.ValidFrom&lt;='2023-06-12'::date   ORDER BY T.ValidFrom DESC   LIMIT 1) R WHERE COALESCE(R.ValidUntil,'infinity'::date)>='2023-06-12'::date;<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0423 \u043c\u0435\u043d\u044f \u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f 150 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">Nested Loop  (cost=0.43..124520.84 rows=100000 width=23) (actual time=3.551..148.543 rows=10000 loops=1)   ->  Function Scan on generate_series g  (cost=0.00..1000.00 rows=100000 width=4) (actual time=3.512..8.371 rows=100000 loops=1)   ->  Subquery Scan on r  (cost=0.42..1.23 rows=1 width=23) (actual time=0.001..0.001 rows=0 loops=100000)         Filter: (COALESCE(r.validuntil, 'infinity'::date) >= '2023-06-12'::date)         ->  Limit  (cost=0.42..1.21 rows=1 width=23) (actual time=0.001..0.001 rows=0 loops=100000)               ->  Index Scan Backward using tmp_test_not_range_pk_idx on tmp_test_not_range t  (cost=0.42..5.15 rows=6 width=23) (actual time=0.001..0.001 rows=0 loops=100000)                     Index Cond: ((id = g.n) AND (validfrom &lt;= '2023-06-12'::date)) Planning Time: 0.145 ms Execution Time: 149.595 ms<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0423\u0432\u044b. \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 btree_gist \u0442\u043e\u0436\u0435 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442, \u0445\u043e\u0442\u044c \u0438 \u043d\u0435 \u0441\u0442\u043e\u043b\u044c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e &#8212; \u043d\u0430 20%. \u0427\u0442\u043e, \u0432\u043f\u0440\u043e\u0447\u0435\u043c, \u0442\u043e\u0436\u0435 \u043d\u0435\u043c\u0430\u043b\u043e.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u0447\u0442\u043e btree_gist \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441 \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e. \u0414\u0430, \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 btree_gist \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u044e\u0442 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043d\u043e \u0446\u0435\u043d\u0430 \u044d\u0442\u043e\u0433\u043e &#8212; \u0434\u0435\u0433\u0440\u0430\u0434\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043a\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043f\u043e\u0447\u0442\u0438 \u0432 4 \u0440\u0430\u0437\u0430, \u0430 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 &#8212; 20%. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c btree_gist \u0432 \u0442\u0435\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u0430\u0436\u043d\u0430, \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u044d\u0442\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430, \u043d\u043e \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0436\u0438\u0442\u044c.<\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u0435\u0441\u043b\u0438 \u0434\u043e\u0447\u0438\u0442\u0430\u043b\u0438!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/820455\/\"> https:\/\/habr.com\/ru\/articles\/820455\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 PostgreSQL \u0435\u0441\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b &#8212;  \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 (range). \u041e\u043d\u0438 \u0432\u0435\u0441\u044c\u043c\u0430 \u0443\u0434\u043e\u0431\u043d\u044b \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438. \u0414\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 GIST \u0438\u043d\u0434\u0435\u043a\u0441. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0447\u0430\u0441\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 BTREE \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0441 GIST, \u0447\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c <a href=\"https:\/\/www.postgresql.org\/docs\/current\/btree-gist.html\" rel=\"noopener noreferrer nofollow\">btree_gist<\/a>. \u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0435 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 btree_gist \u043c\u044b \u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p>\u0414\u043b\u044f \u041b\u041b &#8212; \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 btree_gist \u0431\u0443\u0434\u0435\u0442 \u043f\u043b\u043e\u0445\u043e.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043f\u043e \u0434\u0430\u0442\u0430\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0430. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0438 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0434\u0430\u0442, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u0438 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0431\u044b\u043b\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"center\">\u041a\u043b\u0438\u0435\u043d\u0442<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0414\u0430\u0442\u0430 \u0441<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0414\u0430\u0442\u0430 \u043f\u043e<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0424\u0430\u043c\u0438\u043b\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"center\">\u0422\u0435\u043b\u0435\u0444\u043e\u043d<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">2020-01-01<\/p>\n<\/td>\n<td>\n<p align=\"left\">2020-07-12<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0432\u0430\u043d\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">+74991001010<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">2021-05-20<\/p>\n<\/td>\n<td>\n<p align=\"left\">2023-02-28<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0442\u0440\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">+74991001010<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">2023-03-01<\/p>\n<\/td>\n<td>\n<p align=\"left\">2023-09-11<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0435\u0442\u0440\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">+74959990101<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">2023-12-22<\/p>\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\u0421\u0438\u0434\u043e\u0440\u043e\u0432\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">+74959990101<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0443\u0441\u0442\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#171;\u0414\u0430\u0442\u0430 \u043f\u043e&#187; \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0441 &#171;\u0414\u0430\u0442\u044b \u0441&#187; \u0434\u043e \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0441\u0442\u0438. \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0442\u044c\u0441\u044f, \u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430\u043c\u0438 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u044b\u0432\u044b \u043d\u0430 \u0442\u043e \u0432\u0440\u0435\u043c\u044f, \u043f\u043e\u043a\u0430 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 \u043d\u0435 \u0431\u044b\u043b\u043e. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0440\u0430\u0437\u0440\u044b\u0432\u044b \u043c\u0435\u0436\u0434\u0443 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430\u043c\u0438 \u043c\u044b \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e GIST \u0438\u043d\u0434\u0435\u043a\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432, \u043d\u043e \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0440\u0430\u0437\u0440\u044b\u0432\u043e\u0432. \u0410 \u0442\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0437\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435\u043c \u0440\u0430\u0437\u0440\u044b\u0432\u043e\u0432 \u0431\u0435\u0437 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u0442\u043e \u0434\u043b\u044f \u0446\u0435\u043b\u0435\u0439 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 BTREE \u0438 btree_gist \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442.<\/p>\n<p>\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0434\u0435\u043b\u0430\u0432 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (Id) \u043f\u0440\u043e\u0441\u0442\u043e integer, \u0430 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u0443\u0441\u0442\u044c \u0431\u0443\u0434\u0443\u0442 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0438 \u0447\u0438\u0441\u043b\u043e\u043c. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE tmp_test_range (   Id    integer       NOT NULL,   Valid daterange     NOT NULL, -- \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0434\u0430\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430   Code  integer       NOT NULL,   Amt   decimal(16,2) NOT NULL,   CONSTRAINT tmp_test_range_PK_idx     EXCLUDE USING GIST (Id WITH =, Valid WITH &amp;&amp;) -- \u0437\u0430\u043f\u0440\u0435\u0442 \u043d\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435  );<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u043d\u0430\u0448\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<pre><code class=\"pgsql\">INSERT INTO tmp_test_range (Id, Valid, Code, Amt) SELECT G.n \/ 10 AS Id,   daterange(     ( '2023-01-01'::date       + '1 day'::interval       * (G.n % 10) * 30 )::date,     CASE WHEN G.n % 10 = 9 THEN NULL       ELSE         ( '2023-01-01'::date           + '1 day'::interval           * ( (G.n % 10) * 30                + (G.n % 10 + 1) * 3 ) )::date END,     '[)' ),   G.n AS Code,   G.n*0.5 AS Amt FROM generate_series(0,999999) G(n);<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041d\u0430 \u043c\u043e\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 PostgreSQL 15 \u044d\u0442\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 45 \u0441\u0435\u043a\u0443\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">Insert on tmp_test_range  (cost=0.00..67500.00 rows=0 width=0) (actual time=45364.169..45364.170 rows=0 loops=1)   ->  Function Scan on generate_series g  (cost=0.00..67500.00 rows=1000000 width=58) (actual time=63.500..1115.834 rows=1000000 loops=1) Planning Time: 0.068 ms Execution Time: 45373.995 ms<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f btree_gist \u0438 GIST. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE tmp_test_not_range (   Id         integer       NOT NULL,   ValidFrom  date          NOT NULL,   ValidUntil date          NULL,   Code       integer       NOT NULL,   Amt        decimal(16,2) NOT NULL,   CONSTRAINT tmp_test_not_range_PK_idx     PRIMARY KEY (Id, ValidFrom) INCLUDE (ValidUntil) );<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432 \u0434\u0430\u0442 BTREE \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442, \u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u044d\u0442\u043e \u0441\u0430\u043c\u0438\u043c \u0447\u0435\u0440\u0435\u0437 \u0442\u0440\u0438\u0433\u0433\u0435\u0440. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430:<\/p>\n<pre><code class=\"pgsql\">CREATE OR REPLACE FUNCTION   tmp_test_not_range_before_insert_update_tfn() RETURNS TRIGGER AS $func$ &lt;&lt;func>> DECLARE   ValidFrom  date;   ValidUntil date; BEGIN   -- \u0414\u0430\u0442\u0430 \u043a\u043e\u043d\u0446\u0430 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043b\u0438 \u0440\u0430\u0432\u043d\u0430 \u0434\u0430\u0442\u0435 \u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430   IF NEW.ValidFrom>COALESCE(NEW.ValidUntil,NEW.ValidFrom) THEN     RAISE EXCEPTION 'ValidUntil must be higher or equal ValidFrom';   END IF;    -- \u0418\u0449\u0435\u043c, \u043d\u0435\u0442 \u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432   -- \u041f\u0440\u0438 UPDATE \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0438\u0437 \u043f\u043e\u0438\u0441\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c   SELECT F.ValidFrom, F.ValidUntil   FROM (     SELECT T.ValidFrom, T.ValidUntil      FROM tmp_test_not_range T     WHERE T.Id=NEW.Id       AND ( OLD.Id IS NULL         OR NOT (T.Id=OLD.Id AND T.ValidFrom=OLD.ValidFrom) )     AND T.ValidFrom&lt;=COALESCE(NEW.ValidUntil,'infinity'::date)     ORDER BY T.ValidFrom DESC     LIMIT 1 ) F   WHERE COALESCE(F.ValidUntil,'infinity'::date)>=NEW.ValidFrom   INTO func.ValidFrom, func.ValidUntil;    -- \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e, \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438   IF func.ValidFrom IS NOT NULL THEN     RAISE EXCEPTION       'Id % ValidFrom % intersect with ValidFrom % and ValidUntil %',       NEW.Id, New.ValidFrom, func.ValidFrom, func.ValidUntil;   END IF;    RETURN NEW; END; $func$ LANGUAGE plpgsql;<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u0442\u0440\u0438\u0433\u0433\u0435\u0440:<\/p>\n<pre><code class=\"pgsql\">CREATE OR REPLACE TRIGGER tmp_test_not_range_before_insert_update_trg   BEFORE INSERT OR UPDATE OF Id, ValidFrom, ValidUntil   ON tmp_test_not_range FOR EACH ROW   EXECUTE FUNCTION tmp_test_not_range_before_insert_update_tfn();<\/code><\/pre>\n<p>\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0438 \u044d\u0442\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0442\u0435\u043c\u0438 \u0436\u0435 \u0441\u0430\u043c\u044b\u043c\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438:<\/p>\n<pre><code class=\"pgsql\">INSERT INTO tmp_test_not_range (Id,   ValidFrom, ValidUntil, Code, Amt) SELECT G.n \/ 10 AS Id,   ( '2023-01-01'::date     + '1 day'::interval     * (G.n % 10) * 30 )::date,   CASE WHEN G.n % 10 = 9 THEN NULL     ELSE       ( '2023-01-01'::date         + '1 day'::interval         * ( (G.n % 10) * 30              + (G.n % 10 + 1) * 3 ) )::date END,   G.n AS Code,   G.n*0.5 AS Amt FROM generate_series(0,999999) G(n);<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041d\u0430 \u043c\u043e\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 PostgreSQL 15 \u044d\u0442\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0435\u043d\u0435\u0435 12 \u0441\u0435\u043a\u0443\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">Insert on tmp_test_not_range  (cost=0.00..65000.00 rows=0 width=0) (actual time=11581.151..11581.151 rows=0 loops=1)   ->  Function Scan on generate_series g  (cost=0.00..65000.00 rows=1000000 width=34) (actual time=83.449..890.624 rows=1000000 loops=1) Planning Time: 0.086 ms Trigger tmp_test_not_range_after_insert_update_trg: time=8429.938 calls=1000000 Execution Time: 11621.851 ms<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0442\u0430\u0432\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e btree_gist \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0447\u0442\u0438 \u0432 4 \u0440\u0430\u0437\u0430 \u0432\u0441\u0442\u0430\u0432\u043a\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e BTREE \u043f\u043b\u044e\u0441 \u0438\u0437\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0430 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0435.<\/p>\n<p>\u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c btree_gist \u0434\u0430\u0441\u0442 \u0432\u044b\u0438\u0433\u0440\u044b\u0448 \u0445\u043e\u0442\u044f \u0431\u044b \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445? \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c. \u0412\u044b\u0431\u0435\u0440\u0435\u043c \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u043c \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438 100 \u0442\u044b\u0441. \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 Id \u0432\u0441\u0435\u0433\u043e 10 \u0442\u044b\u0441 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 Id \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u0430\u0442\u0443:<\/p>\n<pre><code class=\"pgsql\">SELECT R.Id, R.Valid, R.Code, R.Amt FROM generate_series(0,999999,10) G(n) JOIN tmp_test_range R ON R.Id=G.n AND R.Valid@>'2023-06-12'::date;<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0423 \u043c\u0435\u043d\u044f \u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f 180 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">Hash Join  (cost=11992.91..20109.38 rows=99147 width=28) (actual time=155.387..179.831 rows=10000 loops=1)   Hash Cond: (g.n = r.id)   ->  Function Scan on generate_series g  (cost=0.00..1000.00 rows=100000 width=4) (actual time=7.546..11.391 rows=100000 loops=1)   ->  Hash  (cost=10753.36..10753.36 rows=99164 width=28) (actual time=147.726..147.729 rows=100000 loops=1)         Buckets: 131072  Batches: 1  Memory Usage: 7368kB         ->  Bitmap Heap Scan on tmp_test_range r  (cost=1769.81..10753.36 rows=99164 width=28) (actual time=106.657..132.703 rows=100000 loops=1)               Recheck Cond: (valid @> '2023-06-12'::date)               Heap Blocks: exact=7744               ->  Bitmap Index Scan on tmp_test_range_pk_idx  (cost=0.00..1745.02 rows=99164 width=0) (actual time=105.592..105.592 rows=100000 loops=1)                     Index Cond: (valid @> '2023-06-12'::date) Planning Time: 0.179 ms Execution Time: 180.755 ms<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435:<\/p>\n<pre><code class=\"pgsql\">SELECT R.Id, R.ValidFrom, R.ValidUntil, R.Code, R.Amt FROM generate_series(0,999999,10) G(n) CROSS JOIN LATERAL (   SELECT T.Id, T.ValidFrom, T.ValidUntil, T.Code, T.Amt   FROM tmp_test_not_range T   WHERE T.Id=G.n AND T.ValidFrom&lt;='2023-06-12'::date   ORDER BY T.ValidFrom DESC   LIMIT 1) R WHERE COALESCE(R.ValidUntil,'infinity'::date)>='2023-06-12'::date;<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0423 \u043c\u0435\u043d\u044f \u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f 150 \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">Nested Loop  (cost=0.43..124520.84 rows=100000 width=23) (actual time=3.551..148.543 rows=10000 loops=1)   ->  Function Scan on generate_series g  (cost=0.00..1000.00 rows=100000 width=4) (actual time=3.512..8.371 rows=100000 loops=1)   ->  Subquery Scan on r  (cost=0.42..1.23 rows=1 width=23) (actual time=0.001..0.001 rows=0 loops=100000)         Filter: (COALESCE(r.validuntil, 'infinity'::date) >= '2023-06-12'::date)         ->  Limit  (cost=0.42..1.21 rows=1 width=23) (actual time=0.001..0.001 rows=0 loops=100000)               ->  Index Scan Backward using tmp_test_not_range_pk_idx on tmp_test_not_range t  (cost=0.42..5.15 rows=6 width=23) (actual time=0.001..0.001 rows=0 loops=100000)                     Index Cond: ((id = g.n) AND (validfrom &lt;= '2023-06-12'::date)) Planning Time: 0.145 ms Execution Time: 149.595 ms<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0423\u0432\u044b. \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 btree_gist \u0442\u043e\u0436\u0435 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442, \u0445\u043e\u0442\u044c \u0438 \u043d\u0435 \u0441\u0442\u043e\u043b\u044c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e &#8212; \u043d\u0430 20%. \u0427\u0442\u043e, \u0432\u043f\u0440\u043e\u0447\u0435\u043c, \u0442\u043e\u0436\u0435 \u043d\u0435\u043c\u0430\u043b\u043e.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c, \u0447\u0442\u043e btree_gist \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441 \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e. \u0414\u0430, \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 btree_gist \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u044e\u0442 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043d\u043e \u0446\u0435\u043d\u0430 \u044d\u0442\u043e\u0433\u043e &#8212; \u0434\u0435\u0433\u0440\u0430\u0434\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043a\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043f\u043e\u0447\u0442\u0438 \u0432 4 \u0440\u0430\u0437\u0430, \u0430 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 &#8212; 20%. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c btree_gist \u0432 \u0442\u0435\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u0430\u0436\u043d\u0430, \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u044d\u0442\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430, \u043d\u043e \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0436\u0438\u0442\u044c.<\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u0435\u0441\u043b\u0438 \u0434\u043e\u0447\u0438\u0442\u0430\u043b\u0438!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/820455\/\"> https:\/\/habr.com\/ru\/articles\/820455\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-378369","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/378369","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=378369"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/378369\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=378369"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=378369"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=378369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}