powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / оптимизация запроса
25 сообщений из 57, страница 1 из 3
оптимизация запроса
    #38125813
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго дня!

В целях быстродействия функции решил оптимизировать в ней запрос:
сменить медленные подзапросы на LEFT JOIN.

вот исходный запрос:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT cl."ID", 
(SELECT "O_T_IDS"."NAME" FROM "O_T_IDS" WHERE "O_T_IDS"."ID" = cl."O_T_ID"),
(SELECT "P_T_IDS"."NAME" FROM "P_T_IDS" WHERE "P_T_IDS"."ID" = cl."P_T_ID"),
(SELECT "D_IDS"."NAME" FROM "D_IDS" WHERE "D_IDS"."ID" = cl."D_ID"),
FROM cl 
WHERE cl."S_ID" = 1
AND cl."EXPIRATION_TIME" is NULL 
order by cl."ID" asc;



перешел на LEFT JOIN:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT cl."ID", "O_T_IDS"."NAME", "P_T_IDS"."NAME", "D_IDS"."NAME",
FROM cl 
LEFT JOIN "O_T_IDS" ON "O_T_IDS"."ID" = cl."O_T_ID"
LEFT JOIN "P_T_IDS" ON "P_T_IDS"."ID" = cl."P_T_ID"
LEFT JOIN "D_IDS" ON "D_IDS"."ID" = cl."D_ID"
WHERE cl."S_ID" = 1
AND cl."EXPIRATION_TIME" is NULL 
order by cl."ID" asc;



как и ожидалось, результат получаем одинаковый.
Далее для сравнения запустил выполнение обоих запросов в цикле на 10000 повторений.
Результат:

1-й запрос:

QUERY PLAN
Result (cost=0.00..0.26 rows=1 width=0) (actual time=752.993..834.105 rows=50000 loops=1)
Total runtime: 894.151 ms

2-й запрос:

QUERY PLAN
Result (cost=0.00..0.26 rows=1 width=0) (actual time=875.821..957.876 rows=50000 loops=1)
Total runtime: 1017.922 ms

чем же запрос с использованием LEFT JOIN лучше запроса с использованием подзапросов,
если он медленнее выполняется?
...
Рейтинг: 0 / 0
оптимизация запроса
    #38125831
/\/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Viacheslav_mihalich,

Потому что сильно напоминает анекдот: "Мне Рабинович в коридоре напел".

Приведите нормальный план запроса, чтобы были видны какие индексы используются и используются ли вообще.

"Как и ожидалось..." -- если Вы намекаете на то, что PostgreSQL не годится для оптимальных запросов, то специально для Вас ответ: "таки да".

Вы в обеих запросах используете одно и то же условие: cl.s_id = 1 AND cl.expiration_time IS NULL. Только в первом запросе дополнительные данные вытягиваются только из отобранных данных (то есть после фильтра), а во втором фильтр применяется уже после того, как туева хуча дополнительных данных присоединена к результатам запроса. Вот почему второй вариант хуже.

При этом совершенно не ясна судьба фильтрации: есть ли индекс по cl.s_id, применяется ли он (по соображениям селективности), может быть есть смысл применить условный фильтр.

Приведите нормальный план запроса.
Сразу можете привести долю записей с cl.s_id = 1 из общей массы, распределение по другим значениям. А так же в комбинации с cl.expitation_time. Это чтобы прикинуть возможности индекса.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38125847
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну, спасибо!
Сразу 2 удовольствия в одном:
и ответ и анекдот

для запроса:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT cl."ID",
"OWNER_TYPE_IDS"."NAME",
"PAYMENT_TYPE_IDS"."NAME",
"DISTRICT_IDS"."NAME"
FROM "CLINICS" cl 
LEFT JOIN "OWNER_TYPE_IDS" ON "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"
LEFT JOIN "PAYMENT_TYPE_IDS" ON "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"
LEFT JOIN "DISTRICT_IDS" ON "DISTRICT_IDS"."ID" = cl."DISTRICT_ID"
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL order by cl."ID" asc;



план:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
"QUERY PLAN"
"Sort  (cost=4.34..4.35 rows=1 width=318)"
"  Sort Key: cl.""ID"""
"  ->  Nested Loop Left Join  (cost=0.00..4.33 rows=1 width=318)"
"        Join Filter: (""PAYMENT_TYPE_IDS"".""ID"" = cl.""PAYMENT_TYPE_ID"")"
"        ->  Nested Loop Left Join  (cost=0.00..3.27 rows=1 width=240)"
"              Join Filter: (""DISTRICT_IDS"".""ID"" = cl.""DISTRICT_ID"")"
"              ->  Nested Loop Left Join  (cost=0.00..2.18 rows=1 width=98)"
"                    Join Filter: (""OWNER_TYPE_IDS"".""ID"" = cl.""OWNER_TYPE_ID"")"
"                    ->  Seq Scan on ""CLINICS"" cl  (cost=0.00..1.09 rows=1 width=20)"
"                          Filter: ((""EXPIRATION_TIME"" IS NULL) AND (""SETTLEMENT_ID"" = 1))"
"                    ->  Seq Scan on ""OWNER_TYPE_IDS""  (cost=0.00..1.04 rows=4 width=86)"
"              ->  Seq Scan on ""DISTRICT_IDS""  (cost=0.00..1.04 rows=4 width=150)"
"        ->  Seq Scan on ""PAYMENT_TYPE_IDS""  (cost=0.00..1.03 rows=3 width=86)"




для запроса:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
SELECT cl."ID", 
(SELECT "OWNER_TYPE_IDS"."NAME" FROM "OWNER_TYPE_IDS" WHERE "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"),
(SELECT "PAYMENT_TYPE_IDS"."NAME" FROM "PAYMENT_TYPE_IDS" WHERE "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"),
(SELECT "DISTRICT_IDS"."NAME" FROM "DISTRICT_IDS" WHERE "DISTRICT_IDS"."ID" = cl."DISTRICT_ID")
FROM "CLINICS" cl 
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL order by cl."ID" asc;



план:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
"QUERY PLAN"
"Sort  (cost=4.23..4.24 rows=1 width=20)"
"  Sort Key: cl.""ID"""
"  ->  Seq Scan on ""CLINICS"" cl  (cost=0.00..4.22 rows=1 width=20)"
"        Filter: ((""EXPIRATION_TIME"" IS NULL) AND (""SETTLEMENT_ID"" = 1))"
"        SubPlan 1"
"          ->  Seq Scan on ""OWNER_TYPE_IDS""  (cost=0.00..1.05 rows=1 width=82)"
"                Filter: (""ID"" = cl.""OWNER_TYPE_ID"")"
"        SubPlan 2"
"          ->  Seq Scan on ""PAYMENT_TYPE_IDS""  (cost=0.00..1.04 rows=1 width=82)"
"                Filter: (""ID"" = cl.""PAYMENT_TYPE_ID"")"
"        SubPlan 3"
"          ->  Seq Scan on ""DISTRICT_IDS""  (cost=0.00..1.05 rows=1 width=146)"
"                Filter: (""ID"" = cl.""DISTRICT_ID"")"
...
Рейтинг: 0 / 0
оптимизация запроса
    #38125852
/\/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Viacheslav_mihalich,

Так и есть!

Seq Scan on ""CLINICS"" cl (cost=0.00..1.09 rows=1 width=20)"
Filter: ((""EXPIRATION_TIME"" IS NULL) AND (""SETTLEMENT_ID"" = 1))"

В обеих запросах это не вызывает совершенно никаких эмоций. С учетом предыдущих предложений обратить внимание на построение индекса.

Вам на будущее: всегда приводите реальные запросы с которыми работаете. Потому что в 95% случаев выясняется, что запрос был другим, а вся беседа была зря.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126048
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viacheslav_mihalich,

вы приводите
а)результаты explain analyze а не explain
б)На рабочих данных а не на пустой таблице (то что вы привели)

планы запросов ЗАВИСЯТ от данных в таблице и смотреть планы на пустых таблицах смысла ровно 0.

Если возращается 50000 строк в запросе то оба варианта будут небыстрыми...
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126223
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привожу с нагруженной таблицей в 100008 записей:
1.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
explain analyze SELECT cl."ID",
"OWNER_TYPE_IDS"."NAME",
"PAYMENT_TYPE_IDS"."NAME",
"DISTRICT_IDS"."NAME"
FROM "CLINICS" cl 
LEFT JOIN "OWNER_TYPE_IDS" ON "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"
LEFT JOIN "PAYMENT_TYPE_IDS" ON "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"
LEFT JOIN "DISTRICT_IDS" ON "DISTRICT_IDS"."ID" = cl."DISTRICT_ID"
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL order by cl."ID" asc;



QUERY PLAN:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
"Nested Loop Left Join  (cost=0.00..13172.67 rows=50122 width=318) (actual time=0.072..2541.229 rows=50011 loops=1)"
"  Join Filter: ("DISTRICT_IDS"."ID" = cl."DISTRICT_ID")"
"  ->  Nested Loop Left Join  (cost=0.00..10164.30 rows=50122 width=176) (actual time=0.057..1684.598 rows=50011 loops=1)"
"        Join Filter: ("PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID")"
"        ->  Nested Loop Left Join  (cost=0.00..7907.77 rows=50122 width=98) (actual time=0.034..955.021 rows=50011 loops=1)"
"              Join Filter: ("OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID")"
"              ->  Index Scan using "CLINICS_pkey" on "CLINICS" cl  (cost=0.00..4899.40 rows=50122 width=20) (actual time=0.016..89.975 rows=50011 loops=1)"
"                    Filter: (("EXPIRATION_TIME" IS NULL) AND ("SETTLEMENT_ID" = 1))"
"              ->  Materialize  (cost=0.00..1.06 rows=4 width=86) (actual time=0.001..0.006 rows=4 loops=50011)"
"                    ->  Seq Scan on "OWNER_TYPE_IDS"  (cost=0.00..1.04 rows=4 width=86) (actual time=0.003..0.008 rows=4 loops=1)"
"        ->  Materialize  (cost=0.00..1.04 rows=3 width=86) (actual time=0.001..0.005 rows=3 loops=50011)"
"              ->  Seq Scan on "PAYMENT_TYPE_IDS"  (cost=0.00..1.03 rows=3 width=86) (actual time=0.002..0.006 rows=3 loops=1)"
"  ->  Materialize  (cost=0.00..1.06 rows=4 width=150) (actual time=0.001..0.006 rows=4 loops=50011)"
"        ->  Seq Scan on "DISTRICT_IDS"  (cost=0.00..1.04 rows=4 width=150) (actual time=0.002..0.008 rows=4 loops=1)"
"Total runtime: 2604.619 ms"



2.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
explain analyze SELECT cl."ID", 
(SELECT "OWNER_TYPE_IDS"."NAME" FROM "OWNER_TYPE_IDS" WHERE "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"),
(SELECT "PAYMENT_TYPE_IDS"."NAME" FROM "PAYMENT_TYPE_IDS" WHERE "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"),
(SELECT "DISTRICT_IDS"."NAME" FROM "DISTRICT_IDS" WHERE "DISTRICT_IDS"."ID" = cl."DISTRICT_ID")
FROM "CLINICS" cl 
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL order by cl."ID" asc;



QUERY PLAN:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
"Index Scan using "CLINICS_pkey" on "CLINICS" cl  (cost=0.00..162157.18 rows=50122 width=20) (actual time=0.051..1586.286 rows=50011 loops=1)"
"  Filter: (("EXPIRATION_TIME" IS NULL) AND ("SETTLEMENT_ID" = 1))"
"  SubPlan 1"
"    ->  Seq Scan on "OWNER_TYPE_IDS"  (cost=0.00..1.05 rows=1 width=82) (actual time=0.002..0.004 rows=1 loops=50011)"
"          Filter: ("ID" = cl."OWNER_TYPE_ID")"
"  SubPlan 2"
"    ->  Seq Scan on "PAYMENT_TYPE_IDS"  (cost=0.00..1.04 rows=1 width=82) (actual time=0.002..0.004 rows=1 loops=50011)"
"          Filter: ("ID" = cl."PAYMENT_TYPE_ID")"
"  SubPlan 3"
"    ->  Seq Scan on "DISTRICT_IDS"  (cost=0.00..1.05 rows=1 width=146) (actual time=0.002..0.004 rows=1 loops=50011)"
"          Filter: ("ID" = cl."DISTRICT_ID")"
"Total runtime: 1651.062 ms"



сама таблица:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
CREATE TABLE "CLINICS"
(
  "ID" bigserial NOT NULL,
  "NAME" character varying(32),
  "NUMBER" integer, -- Number of the clinic, e.g. N35
  "STREET" character varying(64) NOT NULL,
  "SETTLEMENT_ID" integer NOT NULL,
  "IS_CHILDRENS" boolean,
  "IS_RECOVERY" boolean,
  "IS_DENTAL" boolean,
  "IS_NIGHT" boolean,
  "TELEPHONES" character varying(64),
  "WEBSITE" character varying(64),
  "OWNER_TYPE_ID" integer,
  "PAYMENT_TYPE_ID" integer,
  "DISTRICT_ID" integer,
  "EXPIRATION_TIME" timestamp without time zone,
  "HOUSE_NUM" integer NOT NULL,
  "HOUSING_NUM" integer,
  "IS_DIAGNOSTIC" boolean,
  "IS_CONSULTING" boolean,
  "INFO" character varying(2048),
  "IMAGE" character varying(64),
  CONSTRAINT "CLINICS_pkey" PRIMARY KEY ("ID" ),
  CONSTRAINT "DISTRICT_ID" FOREIGN KEY ("DISTRICT_ID")
      REFERENCES "DISTRICT_IDS" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE,
  CONSTRAINT "OWNER_TYPE_ID" FOREIGN KEY ("OWNER_TYPE_ID")
      REFERENCES "OWNER_TYPE_IDS" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "PAYMENT_TYPE_ID" FOREIGN KEY ("PAYMENT_TYPE_ID")
      REFERENCES "PAYMENT_TYPE_IDS" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "SETTLEMENT_ID" FOREIGN KEY ("SETTLEMENT_ID")
      REFERENCES "SETTLEMENTS" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT positive_distr_id CHECK ("DISTRICT_ID" > 0),
  CONSTRAINT positive_house_num CHECK ("HOUSE_NUM" > 0),
  CONSTRAINT positive_housing_num CHECK ("HOUSING_NUM" > 0),
  CONSTRAINT positive_number CHECK ("NUMBER" > 0),
  CONSTRAINT positive_owner_type_id CHECK ("OWNER_TYPE_ID" > 0),
  CONSTRAINT positive_payment_type_id CHECK ("PAYMENT_TYPE_ID" > 0),
  CONSTRAINT positive_set_id CHECK ("SETTLEMENT_ID" > 0)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE "CLINICS"
  OWNER TO postgres;
COMMENT ON COLUMN "CLINICS"."NUMBER" IS 'Number of the clinic, e.g. N35';


-- Index: "fki_DISTRICT_ID"

-- DROP INDEX "fki_DISTRICT_ID";

CREATE INDEX "fki_DISTRICT_ID"
  ON "CLINICS"
  USING btree
  ("DISTRICT_ID" );

-- Index: "fki_OWNER_TYPE_ID"

-- DROP INDEX "fki_OWNER_TYPE_ID";

CREATE INDEX "fki_OWNER_TYPE_ID"
  ON "CLINICS"
  USING btree
  ("OWNER_TYPE_ID" );

-- Index: "fki_PAYMENT_TYPE_ID"

-- DROP INDEX "fki_PAYMENT_TYPE_ID";

CREATE INDEX "fki_PAYMENT_TYPE_ID"
  ON "CLINICS"
  USING btree
  ("PAYMENT_TYPE_ID" );

-- Index: "fki_SETTLEMENT_ID"

-- DROP INDEX "fki_SETTLEMENT_ID";

CREATE INDEX "fki_SETTLEMENT_ID"
  ON "CLINICS"
  USING btree
  ("SETTLEMENT_ID" );

-- Index: uniq_duplicate_record_name

-- DROP INDEX uniq_duplicate_record_name;

CREATE UNIQUE INDEX uniq_duplicate_record_name
  ON "CLINICS"
  USING btree
  ("NAME" COLLATE pg_catalog."default" , "STREET" COLLATE pg_catalog."default" , "SETTLEMENT_ID" , "HOUSE_NUM" )
  WHERE "EXPIRATION_TIME" IS NULL;

-- Index: uniq_duplicate_record_number

-- DROP INDEX uniq_duplicate_record_number;

CREATE UNIQUE INDEX uniq_duplicate_record_number
  ON "CLINICS"
  USING btree
  ("NUMBER" , "STREET" COLLATE pg_catalog."default" , "SETTLEMENT_ID" , "HOUSE_NUM" )
  WHERE "EXPIRATION_TIME" IS NULL;
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126237
/\/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Viacheslav_mihalich,

Пожалуйста, приведите результат запросов:

Код: sql
1.
2.
3.
4.
5.
6.
SELECT
  settlement_id,
  COUNT(*)
FROM clinics
GROUP BY settlement_id
;



Код: sql
1.
2.
3.
4.
5.
6.
SELECT
  COUNT(*) AS cou,
  SUM(CASE WHEN settlement_id = 1 THEN 1 ELSE 0 END) AS cou_settlement_one,
  SUM(CASE WHEN (settlement_id = 1) AND (expitation_time IS NULL) THEN 1 ELSE 0 END) AS cou_
FROM clinics
;
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126282
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1.
Код: plsql
1.
2.
3.
4.
5.
SELECT
  "SETTLEMENT_ID",
  COUNT(*)
FROM "CLINICS"
GROUP BY "SETTLEMENT_ID";



результат:

Код: sql
1.
2.
3.
4.
SETTLEMENT_ID	   count
1	           50012
2	           49995
3	           1



2.
Код: plsql
1.
2.
3.
4.
5.
SELECT
  COUNT(*) AS cou,
  SUM(CASE WHEN "SETTLEMENT_ID" = 1 THEN 1 ELSE 0 END) AS cou_settlement_one,
  SUM(CASE WHEN ("SETTLEMENT_ID" = 1) AND ("EXPIRATION_TIME" IS NULL) THEN 1 ELSE 0 END) AS cou_
FROM "CLINICS";



результат:

Код: sql
1.
2.
cou	cou_settlement_one      cou_
100008	50012               	50011
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126286
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
с "EXPIRATION_TIME" IS NULL маловато конечно данных,
по полю "SETTLEMENT_ID" данные отличаются.

Возможно такие данные не показательны,
могу по-разнообразней таблицу заполнить:
с множеством различных "SETTLEMENT_ID"
и чтобы "EXPIRATION_TIME" IS NULL было по-больше.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126289
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viacheslav_mihalich,

пока у вас в присоединяемых таблицах по 1-2-5 записям план с subrequests вероятнее всего будет быстрее...

я бы попробовал поиграть с cpu_tuple_cost/random_page_cost для получения другого плана но принципиально быстрее не будет...
просто изза того что запрос на 50000 строк быстрым быть не может просто по своим свойствам...

попробуйте выполнить
set enable_material to 0;
и заново выполнить explain analyze запроса с left join
пришлите результаты они очень интересны будут...
вторым этапом попробовать еще сделать
set enable_nestloop to 0;
и тоже сделать explain analyze

если какая то из этих 2х версий будет заметно быстрее можно будет подумать о том в какую стороно крутить *_cost для получения более быстрого плана...
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126331
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
выполнил set enable_material to 0;

затем заново выполнил explain analyze запроса с left join:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
"QUERY PLAN"
"Sort  (cost=24010.65..24135.96 rows=50122 width=318) (actual time=611.814..677.819 rows=50011 loops=1)"
"  Sort Key: cl.""ID"""
"  Sort Method: external sort  Disk: 5080kB"
"  ->  Hash Left Join  (cost=3.25..5362.84 rows=50122 width=318) (actual time=0.097..499.738 rows=50011 loops=1)"
"        Hash Cond: (cl.""DISTRICT_ID"" = ""DISTRICT_IDS"".""ID"")"
"        ->  Hash Left Join  (cost=2.16..4672.57 rows=50122 width=176) (actual time=0.068..360.714 rows=50011 loops=1)"
"              Hash Cond: (cl.""OWNER_TYPE_ID"" = ""OWNER_TYPE_IDS"".""ID"")"
"              ->  Hash Left Join  (cost=1.07..3982.33 rows=50122 width=98) (actual time=0.040..225.509 rows=50011 loops=1)"
"                    Hash Cond: (cl.""PAYMENT_TYPE_ID"" = ""PAYMENT_TYPE_IDS"".""ID"")"
"                    ->  Seq Scan on ""CLINICS"" cl  (cost=0.00..3292.10 rows=50122 width=20) (actual time=0.009..84.545 rows=50011 loops=1)"
"                          Filter: ((""EXPIRATION_TIME"" IS NULL) AND (""SETTLEMENT_ID"" = 1))"
"                    ->  Hash  (cost=1.03..1.03 rows=3 width=86) (actual time=0.018..0.018 rows=3 loops=1)"
"                          Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                          ->  Seq Scan on ""PAYMENT_TYPE_IDS""  (cost=0.00..1.03 rows=3 width=86) (actual time=0.003..0.008 rows=3 loops=1)"
"              ->  Hash  (cost=1.04..1.04 rows=4 width=86) (actual time=0.018..0.018 rows=4 loops=1)"
"                    Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                    ->  Seq Scan on ""OWNER_TYPE_IDS""  (cost=0.00..1.04 rows=4 width=86) (actual time=0.003..0.009 rows=4 loops=1)"
"        ->  Hash  (cost=1.04..1.04 rows=4 width=150) (actual time=0.018..0.018 rows=4 loops=1)"
"              Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"              ->  Seq Scan on ""DISTRICT_IDS""  (cost=0.00..1.04 rows=4 width=150) (actual time=0.003..0.008 rows=4 loops=1)"
"Total runtime: 745.953 ms"



Шайтан!
время выполнения сократилось с 2604.619 ms до 745.953 ms!
А что собственно произошло после выполнения
set enable_material to 0;
в двух словах?

далее выполняю
set enable_nestloop to 0;
затем заново explain analyze запроса с left join:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
"Sort  (cost=24010.65..24135.96 rows=50122 width=318) (actual time=609.695..675.469 rows=50011 loops=1)"
"  Sort Key: cl."ID""
"  Sort Method: external sort  Disk: 5080kB"
"  ->  Hash Left Join  (cost=3.25..5362.84 rows=50122 width=318) (actual time=0.095..497.999 rows=50011 loops=1)"
"        Hash Cond: (cl."DISTRICT_ID" = "DISTRICT_IDS"."ID")"
"        ->  Hash Left Join  (cost=2.16..4672.57 rows=50122 width=176) (actual time=0.066..359.289 rows=50011 loops=1)"
"              Hash Cond: (cl."OWNER_TYPE_ID" = "OWNER_TYPE_IDS"."ID")"
"              ->  Hash Left Join  (cost=1.07..3982.33 rows=50122 width=98) (actual time=0.038..224.672 rows=50011 loops=1)"
"                    Hash Cond: (cl."PAYMENT_TYPE_ID" = "PAYMENT_TYPE_IDS"."ID")"
"                    ->  Seq Scan on "CLINICS" cl  (cost=0.00..3292.10 rows=50122 width=20) (actual time=0.009..84.043 rows=50011 loops=1)"
"                          Filter: (("EXPIRATION_TIME" IS NULL) AND ("SETTLEMENT_ID" = 1))"
"                    ->  Hash  (cost=1.03..1.03 rows=3 width=86) (actual time=0.017..0.017 rows=3 loops=1)"
"                          Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                          ->  Seq Scan on "PAYMENT_TYPE_IDS"  (cost=0.00..1.03 rows=3 width=86) (actual time=0.003..0.008 rows=3 loops=1)"
"              ->  Hash  (cost=1.04..1.04 rows=4 width=86) (actual time=0.018..0.018 rows=4 loops=1)"
"                    Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                    ->  Seq Scan on "OWNER_TYPE_IDS"  (cost=0.00..1.04 rows=4 width=86) (actual time=0.002..0.008 rows=4 loops=1)"
"        ->  Hash  (cost=1.04..1.04 rows=4 width=150) (actual time=0.018..0.018 rows=4 loops=1)"
"              Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"              ->  Seq Scan on "DISTRICT_IDS"  (cost=0.00..1.04 rows=4 width=150) (actual time=0.003..0.008 rows=4 loops=1)"
"Total runtime: 742.405 ms"



время выполнения: "Total runtime: 748.315 ms".

P.S. Причем на время выполнение запроса с подзапросами эти магматические заклинания не подействовали:
было: 1651.062 ms, стало: 1646.203 ms.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126609
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viacheslav_mihalichвыполнил set enable_material to 0;

затем заново выполнил explain analyze запроса с left join:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
"QUERY PLAN"
"Sort  (cost=24010.65..24135.96 rows=50122 width=318) (actual time=611.814..677.819 rows=50011 loops=1)"
"  Sort Key: cl.""ID"""
"  Sort Method: external sort  Disk: 5080kB"
"  ->  Hash Left Join  (cost=3.25..5362.84 rows=50122 width=318) (actual time=0.097..499.738 rows=50011 loops=1)"
"        Hash Cond: (cl.""DISTRICT_ID"" = ""DISTRICT_IDS"".""ID"")"
"        ->  Hash Left Join  (cost=2.16..4672.57 rows=50122 width=176) (actual time=0.068..360.714 rows=50011 loops=1)"
"              Hash Cond: (cl.""OWNER_TYPE_ID"" = ""OWNER_TYPE_IDS"".""ID"")"
"              ->  Hash Left Join  (cost=1.07..3982.33 rows=50122 width=98) (actual time=0.040..225.509 rows=50011 loops=1)"
"                    Hash Cond: (cl.""PAYMENT_TYPE_ID"" = ""PAYMENT_TYPE_IDS"".""ID"")"
"                    ->  Seq Scan on ""CLINICS"" cl  (cost=0.00..3292.10 rows=50122 width=20) (actual time=0.009..84.545 rows=50011 loops=1)"
"                          Filter: ((""EXPIRATION_TIME"" IS NULL) AND (""SETTLEMENT_ID"" = 1))"
"                    ->  Hash  (cost=1.03..1.03 rows=3 width=86) (actual time=0.018..0.018 rows=3 loops=1)"
"                          Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                          ->  Seq Scan on ""PAYMENT_TYPE_IDS""  (cost=0.00..1.03 rows=3 width=86) (actual time=0.003..0.008 rows=3 loops=1)"
"              ->  Hash  (cost=1.04..1.04 rows=4 width=86) (actual time=0.018..0.018 rows=4 loops=1)"
"                    Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                    ->  Seq Scan on ""OWNER_TYPE_IDS""  (cost=0.00..1.04 rows=4 width=86) (actual time=0.003..0.009 rows=4 loops=1)"
"        ->  Hash  (cost=1.04..1.04 rows=4 width=150) (actual time=0.018..0.018 rows=4 loops=1)"
"              Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"              ->  Seq Scan on ""DISTRICT_IDS""  (cost=0.00..1.04 rows=4 width=150) (actual time=0.003..0.008 rows=4 loops=1)"
"Total runtime: 745.953 ms"



Шайтан!
время выполнения сократилось с 2604.619 ms до 745.953 ms!
А что собственно произошло после выполнения
set enable_material to 0;
в двух словах?

далее выполняю
set enable_nestloop to 0;
затем заново explain analyze запроса с left join:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
"Sort  (cost=24010.65..24135.96 rows=50122 width=318) (actual time=609.695..675.469 rows=50011 loops=1)"
"  Sort Key: cl."ID""
"  Sort Method: external sort  Disk: 5080kB"
"  ->  Hash Left Join  (cost=3.25..5362.84 rows=50122 width=318) (actual time=0.095..497.999 rows=50011 loops=1)"
"        Hash Cond: (cl."DISTRICT_ID" = "DISTRICT_IDS"."ID")"
"        ->  Hash Left Join  (cost=2.16..4672.57 rows=50122 width=176) (actual time=0.066..359.289 rows=50011 loops=1)"
"              Hash Cond: (cl."OWNER_TYPE_ID" = "OWNER_TYPE_IDS"."ID")"
"              ->  Hash Left Join  (cost=1.07..3982.33 rows=50122 width=98) (actual time=0.038..224.672 rows=50011 loops=1)"
"                    Hash Cond: (cl."PAYMENT_TYPE_ID" = "PAYMENT_TYPE_IDS"."ID")"
"                    ->  Seq Scan on "CLINICS" cl  (cost=0.00..3292.10 rows=50122 width=20) (actual time=0.009..84.043 rows=50011 loops=1)"
"                          Filter: (("EXPIRATION_TIME" IS NULL) AND ("SETTLEMENT_ID" = 1))"
"                    ->  Hash  (cost=1.03..1.03 rows=3 width=86) (actual time=0.017..0.017 rows=3 loops=1)"
"                          Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                          ->  Seq Scan on "PAYMENT_TYPE_IDS"  (cost=0.00..1.03 rows=3 width=86) (actual time=0.003..0.008 rows=3 loops=1)"
"              ->  Hash  (cost=1.04..1.04 rows=4 width=86) (actual time=0.018..0.018 rows=4 loops=1)"
"                    Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"                    ->  Seq Scan on "OWNER_TYPE_IDS"  (cost=0.00..1.04 rows=4 width=86) (actual time=0.002..0.008 rows=4 loops=1)"
"        ->  Hash  (cost=1.04..1.04 rows=4 width=150) (actual time=0.018..0.018 rows=4 loops=1)"
"              Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"              ->  Seq Scan on "DISTRICT_IDS"  (cost=0.00..1.04 rows=4 width=150) (actual time=0.003..0.008 rows=4 loops=1)"
"Total runtime: 742.405 ms"



время выполнения: "Total runtime: 748.315 ms".

P.S. Причем на время выполнение запроса с подзапросами эти магматические заклинания не подействовали:
было: 1651.062 ms, стало: 1646.203 ms.

а если вы еще set work_mem to '16Mb'; поставите еще быстрее будет (~500ms)
достаточно сочетания enable_material to 0 и повышенного work_mem

а что сделали - запретили использовать неудачный метод соединения таблиц для запроса... я потом поиграю с этим всем и попробую bug-report/test-case разработчикам отправить... не первый раз вижу когда план с материализацией тормозит... что то они с его ценой намудрили.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126735
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,

да, с set work_mem to '16Mb' еще быстрее отработало: "Total runtime: 687.393 ms"
В результате производительность возросла в 3,8 раза.

Видимо "set enable_material to 0;" и "set work_mem to '16Mb' " нужно выполнять каждый раз, как коннектишься к базе,
т.к. при выходе настройка слетает и все возвращается на круги своя.

А за помощь однозначно всем спасибо!
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126761
/\/\/\/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Viacheslav_mihalich,

Эти параметры можно установить раз и навсегда в postgresql.conf (enable_material в разделе Planner Method Configuration).
(Может, там еще что-нибудь можно поднастроить).
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126830
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все здОрово: параметры выставил, на запрос с "explain analyze" полюбовался, порадовался скорости выполнения.
Но возник еще один, возможно глупый вопрос:
"explain analyze" снимаю, чтобы работать с реальными данными, и вижу, что настройки:
"set enable_material to 0;" и "set work_mem to '16Mb' " без "explain analyze" уже не действуют.
Для запроса:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT cl."ID",
"OWNER_TYPE_IDS"."NAME",
"PAYMENT_TYPE_IDS"."NAME",
"DISTRICT_IDS"."NAME"
FROM "CLINICS" cl 
LEFT JOIN "OWNER_TYPE_IDS" ON "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"
LEFT JOIN "PAYMENT_TYPE_IDS" ON "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"
LEFT JOIN "DISTRICT_IDS" ON "DISTRICT_IDS"."ID" = cl."DISTRICT_ID"
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL order by cl."ID" asc;


Суммарное время выполнения запроса: 5032 ms (он же с "explain analyze": 694.387 ms).


Для запроса:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
SELECT cl."ID", 
(SELECT "OWNER_TYPE_IDS"."NAME" FROM "OWNER_TYPE_IDS" WHERE "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"),
(SELECT "PAYMENT_TYPE_IDS"."NAME" FROM "PAYMENT_TYPE_IDS" WHERE "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"),
(SELECT "DISTRICT_IDS"."NAME" FROM "DISTRICT_IDS" WHERE "DISTRICT_IDS"."ID" = cl."DISTRICT_ID")
FROM "CLINICS" cl 
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL order by cl."ID" asc;


Суммарное время выполнения запроса: 4968 ms (он же с "explain analyze": 1642.155 ms).

P.S. других настроек не трогал, данные в таблице не менял.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126860
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viacheslav_mihalich
чем же запрос с использованием LEFT JOIN лучше запроса с использованием подзапросов,
если он медленнее выполняется?


Время выполнения запроса не является критерием качества запроса, и, как ни странно, даже не является критерием производительности запроса.

Приводи io.

По сути же — что в лоб, что по лбу — запросы одинаковы, они даже возможно дают один и тот же план, и выполняются одинаковыми образом.
А то, что ты видишь— просто случайные отклонения, вызванные сторонними причинами.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126869
BLAHBLAHBLAH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Viacheslav_mihalich,

либо в .config, либо
Код: plsql
1.
alter DATABASE BLAHBLAHBLAH set work_mem to '16Mb'


либо при старте каждого коннекта клиента
Код: plsql
1.
set work_mem to '16Mb'
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126872
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
/\/\/\/\/\/\/\
Вы в обеих запросах используете одно и то же условие: cl.s_id = 1 AND cl.expiration_time IS NULL. Только в первом запросе дополнительные данные вытягиваются только из отобранных данных (то есть после фильтра), а во втором фильтр применяется уже после того, как туева хуча дополнительных данных присоединена к результатам запроса. Вот почему второй вариант хуже.




Предположения о порядке вычисления элементов запроса более чем смелые.

Для тех, кто не понимает сарказм, скажу прямо: они неверные.

Так же, как и оценки качества PG как субд.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38126887
/\/\/\/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivПредположения о порядке вычисления элементов запроса более чем смелые.


Пожалуйста, укажите где можно ознакомиться с порядком вычисления, чтобы предположения превратились в уверенность. Какой-нибудь RTFM, желательно официальный.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38127153
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
/\/\/\/\/\/\/\/\/\MasterZivПредположения о порядке вычисления элементов запроса более чем смелые.


Пожалуйста, укажите где можно ознакомиться с порядком вычисления, чтобы предположения превратились в уверенность. Какой-нибудь RTFM, желательно официальный.

Нигде нельзя, порядка вычисления элементов запроса не существует. Порядок не определён.

Есть только один констрейнт -- условия в HAVING при наличии GROUP BY вычисляются после выполнения группировки (или по крайней мере в процессе её выполнения).
...
Рейтинг: 0 / 0
оптимизация запроса
    #38127170
/\/\/\/\/\/\/\/\/\
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv... порядка вычисления элементов запроса не существует. ...

Странно. "Жопа есть, а слова нет". Вычисления есть, а их порядка нет...
Значит Вы тоже не знаете. Жаль.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38127315
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viacheslav_mihalichВсе здОрово: параметры выставил, на запрос с "explain analyze" полюбовался, порадовался скорости выполнения.
Но возник еще один, возможно глупый вопрос:
"explain analyze" снимаю, чтобы работать с реальными данными, и вижу, что настройки:
"set enable_material to 0;" и "set work_mem to '16Mb' " без "explain analyze" уже не действуют.
Для запроса:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT cl."ID",
"OWNER_TYPE_IDS"."NAME",
"PAYMENT_TYPE_IDS"."NAME",
"DISTRICT_IDS"."NAME"
FROM "CLINICS" cl 
LEFT JOIN "OWNER_TYPE_IDS" ON "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"
LEFT JOIN "PAYMENT_TYPE_IDS" ON "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"
LEFT JOIN "DISTRICT_IDS" ON "DISTRICT_IDS"."ID" = cl."DISTRICT_ID"
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL order by cl."ID" asc;


Суммарное время выполнения запроса: 5032 ms (он же с "explain analyze": 694.387 ms).


Для запроса:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
SELECT cl."ID", 
(SELECT "OWNER_TYPE_IDS"."NAME" FROM "OWNER_TYPE_IDS" WHERE "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"),
(SELECT "PAYMENT_TYPE_IDS"."NAME" FROM "PAYMENT_TYPE_IDS" WHERE "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"),
(SELECT "DISTRICT_IDS"."NAME" FROM "DISTRICT_IDS" WHERE "DISTRICT_IDS"."ID" = cl."DISTRICT_ID")
FROM "CLINICS" cl 
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL order by cl."ID" asc;


Суммарное время выполнения запроса: 4968 ms (он же с "explain analyze": 1642.155 ms).

P.S. других настроек не трогал, данные в таблице не менял.

без explain analyze время выполнения запроса включает в себя
a)передачу ответа по сети
б)прием ответа клиентов

попробуйте с локального (для базы) хоста выполнить запрос...
и посмотреть на время...
50000 строк передать по сети вообще долгий процесс
...
Рейтинг: 0 / 0
оптимизация запроса
    #38128790
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,
все дело в том, что именно на localhost-е все это и наблюдается.
Т.е. передачи по сети не было.
...
Рейтинг: 0 / 0
оптимизация запроса
    #38128827
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Viacheslav_mihalichMaxim Boguk,
все дело в том, что именно на localhost-е все это и наблюдается.
Т.е. передачи по сети не было.

а сделайте

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select count(*) from
(
SELECT cl."ID", 
(SELECT "O_T_IDS"."NAME" FROM "O_T_IDS" WHERE "O_T_IDS"."ID" = cl."O_T_ID"),
(SELECT "P_T_IDS"."NAME" FROM "P_T_IDS" WHERE "P_T_IDS"."ID" = cl."P_T_ID"),
(SELECT "D_IDS"."NAME" FROM "D_IDS" WHERE "D_IDS"."ID" = cl."D_ID"),
FROM cl 
WHERE cl."S_ID" = 1
AND cl."EXPIRATION_TIME" is NULL 
order by cl."ID" asc
offset 0
)
as t;



и
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
sekect count(*) from
(SELECT cl."ID", "O_T_IDS"."NAME", "P_T_IDS"."NAME", "D_IDS"."NAME",
FROM cl 
LEFT JOIN "O_T_IDS" ON "O_T_IDS"."ID" = cl."O_T_ID"
LEFT JOIN "P_T_IDS" ON "P_T_IDS"."ID" = cl."P_T_ID"
LEFT JOIN "D_IDS" ON "D_IDS"."ID" = cl."D_ID"
WHERE cl."S_ID" = 1
AND cl."EXPIRATION_TIME" is NULL 
order by cl."ID" asc
offset 0)
as t;



и пришлите какие времена у вас получились
(при work_mem 16Mb и set enable_material to 0;)
...
Рейтинг: 0 / 0
оптимизация запроса
    #38129007
Viacheslav_mihalich
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
При work_mem 16Mb и set enable_material to 0;

1.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select count(*) from
(
SELECT cl."ID", 
(SELECT "OWNER_TYPE_IDS"."NAME" FROM "OWNER_TYPE_IDS" WHERE "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"),
(SELECT "PAYMENT_TYPE_IDS"."NAME" FROM "PAYMENT_TYPE_IDS" WHERE "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"),
(SELECT "DISTRICT_IDS"."NAME" FROM "DISTRICT_IDS" WHERE "DISTRICT_IDS"."ID" = cl."DISTRICT_ID")
FROM "CLINICS" cl 
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL 
order by cl."ID" asc
offset 0
)
as t;



Суммарное время выполнения запроса: 375 ms.
1 строка получена.
count: 50011,

2.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT count(*) from
(SELECT cl."ID", 
"OWNER_TYPE_IDS"."NAME",
"PAYMENT_TYPE_IDS"."NAME",
"DISTRICT_IDS"."NAME"
FROM "CLINICS" cl 
LEFT JOIN "OWNER_TYPE_IDS" ON "OWNER_TYPE_IDS"."ID" = cl."OWNER_TYPE_ID"
LEFT JOIN "PAYMENT_TYPE_IDS" ON "PAYMENT_TYPE_IDS"."ID" = cl."PAYMENT_TYPE_ID"
LEFT JOIN "DISTRICT_IDS" ON "DISTRICT_IDS"."ID" = cl."DISTRICT_ID"
WHERE cl."SETTLEMENT_ID" = 1
AND cl."EXPIRATION_TIME" is NULL 
order by cl."ID" asc
offset 0)
as t;



Суммарное время выполнения запроса: 78 ms.
1 строка получена.
count: 50011.
...
Рейтинг: 0 / 0
25 сообщений из 57, страница 1 из 3
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / оптимизация запроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]