LINUX.ORG.RU

Оптимизировать запрос с array_replace

 


0

2

Есть таблица Responsible, столбец Documents (тип bigint) ид. документа, User(тип []text) - массив пользователей. Нужно при смене пользователя, обновить этого пользователя в массиве User.

Есть такой запрос

UPDATE
	"Responsible"
SET
	"User" = array_replace(
		"User"
	,	'Петров'::text
	,	'Иванов'::text
	)
WHERE
	"Documents" = ANY('{3}') AND
	array_position("User", 'Петров'::text) IS NOT NULL
Но он много потребляет shared hit.
Update on "Responsible"  (cost=0.43..99802.28 rows=154773 width=74) (actual time=179.690..179.691 rows=0 loops=1)
  Buffers: shared hit=136800
  ->  Index Scan using "iDocuments" on "Responsible"  (cost=0.43..99802.28 rows=154773 width=74) (actual time=179.688..179.688 rows=0 loops=1)
        Index Cond: ("Documents" = ANY ('{3}'::bigint[]))
        Filter: (array_position("User", 'Петров'::text) IS NOT NULL)
        Rows Removed by Filter: 149754
        Buffers: shared hit=136800

Используется индекс по Documents, хочется уменьшить потребление shared hit, нет мыслей как это сделать. Как-то переписать запрос или изменить индекс не получается

Тут видно что у тебя большая часть найденных по индексу документов отбрасывается условием по массиву. Т.е. если бы был индексированный поиск по массивуб то запрос работал бы гораздо эффективнее.

Чтобы это провернуть я бы сделал две вещи:

  1. Построить индекс по массиву типа gin
  2. Для поиска использовать оператор @>, потому что он точно умеет работать по индексу.
maxcom ★★★★★
()
Последнее исправление: maxcom (всего исправлений: 1)