Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.07.2023, 22:30   #1
polin11
Форумчанин
 
Регистрация: 07.06.2015
Сообщений: 164
По умолчанию Ускорить простой запрос с CTE

Использую PGSQL, есть простой запрос,


Код:
	EXPLAIN (ANALYZE,BUFFERS)
	WITH data_to_cte AS (
		SELECT
			unnest[1]::integer account
		,	unnest[2]::text user_id
		,	unnest[3]::integer target_id
		FROM
			(
				SELECT
					unnest('{ "{ 7267996,4,96394594 }" }'::text[])::text[]
			) f
	)
	SELECT
		"DocumentsId",
		data_to_cte.*
	FROM
		data_to_cte
	JOIN
		"Documents"
			on "Account" = account AND 
			"Target" = target_id and
			"User" = user_id  AND
			"User" IS NOT NULL
план такой


Код:
Nested Loop  (cost=0.58..8.68 rows=1 width=48) (actual time=23.352..23.353 rows=0 loops=1)
  Buffers: shared hit=16730
  ->  Result  (cost=0.00..0.04 rows=1 width=32) (actual time=0.008..0.012 rows=1 loops=1)
        ->  ProjectSet  (cost=0.00..0.02 rows=1 width=32) (actual time=0.004..0.007 rows=1 loops=1)
              ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=1)
  ->  Index Scan using "iDocuments-AccountUser" on "Documents"  (cost=0.58..8.61 rows=1 width=28) (actual time=23.334..23.334 rows=0 loops=1)
        Index Cond: (("Account" = (((((unnest('{"{ 7267996,4,96394594 }"}'::text[])))::text[]))[1])::integer) AND ("User" = ((((unnest('{"{ 7267996,4,96394594 }"}'::text[])))::text[]))[2]))
        Filter: ((((((unnest('{"{ 7267996,4,96394594 }"}'::text[])))::text[]))[3])::integer = "Target")
        Rows Removed by Filter: 19163
        Buffers: shared hit=16730
Planning Time: 0.318 ms
Execution Time: 23.397 ms

Хочется чтобы использовался такой индекс

Код:
CREATE INDEX "iDocuments-AccountTarget"
	ON "Documents" USING btree
	("Account" NULLS LAST, "Target" NULLS LAST, "User" NULLS LAST)
	WHERE ("User" IS NOT NULL);
Что нужно сделать, возможно переписать запрос?

Например, если указать напрямую Target, то используется нужный индекс
Код:
	EXPLAIN (ANALYZE,BUFFERS)
	WITH data_to_cte AS (
		SELECT
			unnest[1]::integer account
		,	unnest[2]::text user_id
		,	unnest[3]::integer target_id
		FROM
			(
				SELECT
					unnest('{ "{ 7267996,4,96394594 }" }'::text[])::text[]
			) f
	)
	SELECT
		"DocumentsId",
		data_to_cte.*
	FROM
		data_to_cte
	JOIN
		"Documents"
			on "Account" = account AND 
			"Target" = 4 and
			"User" = user_id  AND
			"User" IS NOT NULL
polin11 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ускорить простой запрос polin11 SQL, базы данных 0 21.06.2022 03:07
Ускорить запрос Kot070 Microsoft Office Access 20 22.06.2016 08:23
Объединение больших таблиц - как ускорить запрос? supermike SQL, базы данных 13 30.11.2014 20:51
Простой запрос J4SSektor SQL, базы данных 3 28.04.2013 12:38
Простой запрос Таня84 БД в Delphi 2 04.03.2007 02:49