Hola, esta parte revisa si lo puedes trabajar, los filtros son después de una
lectura de disco o indices para reducir la lectura puedes crear un indice con
los filtros.
Index Cond: ((fulldate >= '2025-01-31 09:30:00'::timestamp without time zone)
AND (fulldate < '2025-02-04 09:30:00'::timestamp without time zone))
Filter: ((hidden_by_contact IS NULL) AND (subclient_id = ANY
('{13579,13580}'::integer[])) AND (id = ANY
('{1381059542,1380939758,1380939757,1380939753}'::integer[])))
Rows Removed by Filter: 2,022,941
Del plan la columna Rows X el planificador cree que va a devolver 4 lineas
usando el indice y la columna rows son las lineas que pasaron realmente por
esta condición.
Si puedes hacer una copia de la base en otro ambiente y correr las estadisticas
para saber si esto mejora es una opción para no tocar produccion.
Ajustar la consulta para hacer explicito la fecha ( fulldate es tipo timestamp
? en tu tabla ? ) en lo personal tengo la costumbre de hacer las consultas de
fecha con esto : to_timestamp o to_date dependiendo del tipo de datos definido
en la tabla.
Podrías probar creando en un indice que incluya los campos de los filtros + la
fecha algo como esto ( debes usar un nombre adecuado a tu standard ).
create index on companies (fulldate, hidden_by_contact, subclient_id, id) ;
create index on companies (fulldate, subclient_id, id) where hidden_by_contact
is null ;
segun el tipo de consultas podrias evaluar particionar la tabla companies.
Prueba en la session cambiando los parámetros ( estos son se HDD no SSD ) eh
encontrado que con maquinas virtuales esto anda mejor, pero prueba, un grupo de
consultas para saber si es mejor o peor, toma un grupo de 10 consultas
significativas.
random_page_cost = 4
effective_io_concurrency = 2
Avisame como te va
NOTA: El depez puedes apretar “add optimization” y agregar cosas que vas
cambiando y veras como van cambiando los planes.
> On 6 Feb 2025, at 1:02 AM, Guillermo E. Villanueva <[email protected]>
> wrote:
>
> https://explain.depesz.com/s/R3Fh
>
> Si lo ejecuto solo hasta el filtro de companies.id <http://companies.id/>
> devuelve el resultado en menos de 1 segundo
> Ese campo es PK de la tabla companies, si lo resuelve tan rápido al de las PK
> porque priorizar un indice de la misma tabla donde las columnas no son PK?
>
> El mar, 4 feb 2025 a las 22:34, Horacio Miranda (<[email protected]
> <mailto:[email protected]>>) escribió:
>> Usa depez para compartir el plan de ejecución por favor
>> New explain | explain.depesz.com
>> explain.depesz.com
>> <favicon.ico>
>> <https://explain.depesz.com/>New explain | explain.depesz.com
>> <https://explain.depesz.com/>
>> explain.depesz.com <https://explain.depesz.com/> <favicon.ico>
>> <https://explain.depesz.com/>
>>
>> Usa esta forma
>> explain (analyze,buffers) select ..
>>
>>
>> Regards,
>> Horacio Miranda
>>
>>> On 5 Feb 2025, at 11:49 AM, Jairo Graterón <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>
>>> Saludos
>>>
>>> id es de tipo int o bigint?
>>>
>>> Prueba con esta otra forma de hacer el IN y nos comentas.
>>>
>>>
>>> "companies"."id" = ANY (ARRAY[1381059542, 1380939758, 1380939757,
>>> 1380939753]::integer)
>>>
>>> si es tipo bigint
>>>
>>> "companies"."id" = ANY (ARRAY[1381059542, 1380939758, 1380939757,
>>> 1380939753]::bigint[])
>>>
>>>
>>>
>>> El mar, 4 feb 2025 a las 12:43, Guillermo E. Villanueva
>>> (<[email protected] <mailto:[email protected]>>) escribió:
>>>> Postgresql 13
>>>> En una query como esta:
>>>> explain select
>>>> *
>>>> from
>>>> "companies"
>>>> inner join "subclients" on "subclients"."id" =
>>>> "companies"."subclient_id"
>>>> inner join "temas" on "temas"."id" = "companies"."main_tema_id"
>>>> left join "domains" on "domains"."id" = "companies"."domain_id"
>>>> left join "papers" on "papers"."id" = "domains"."paper_id"
>>>> left join "tematicas" on "tematicas"."id" = "domains"."tematica_id"
>>>> left join "special_values" on "special_values"."subclient_id" =
>>>> "companies"."subclient_id"
>>>> where
>>>> "companies"."id" in (1381059542, 1380939758, 1380939757, 1380939753)
>>>> and "companies"."subclient_id" in (13579, 13580)
>>>> and companies.fulldate >= '2025-01-31 09:30' and companies.fulldate <
>>>> '2025-02-04 09:30'
>>>> and "companies"."hidden_by_contact" is null
>>>> and (
>>>> (subclients.show_3300 is not true and companies.ep_file
>>>> !~ '_print3300')
>>>> or subclients.show_3300 is true
>>>> )
>>>> and "domains"."p_or_d" in ('p', 'd', 'b')
>>>>
>>>> Tengo este plan de ejecución:
>>>> Nested Loop Left Join (cost=6.70..54.38 rows=1 width=5276)
>>>> -> Nested Loop Left Join (cost=2.28..45.94 rows=1 width=2707)
>>>> -> Nested Loop Left Join (cost=2.13..41.74 rows=1 width=2688)
>>>> -> Nested Loop (cost=1.71..33.80 rows=1 width=2655)
>>>> -> Nested Loop (cost=1.28..25.36 rows=1 width=1781)
>>>> -> Nested Loop (cost=0.86..16.92 rows=1
>>>> width=1673)
>>>> -> Index Scan using
>>>> companies_fulldate_subclient_id_idx on companies (cost=0.57..8.60 rows=1
>>>> width=1113)
>>>> Index Cond: ((fulldate >=
>>>> '2025-01-31 09:30:00'::timestamp without time zone) AND (fulldate <
>>>> '2025-02-04 09:30:00'::timestamp without time zone))
>>>> Filter: ((hidden_by_contact IS NULL)
>>>> AND (subclient_id = ANY ('{13579,13580}'::integer[])) AND (id = ANY
>>>> ('{1381059542,1380939758,1380939757,1380939753}'::integer[])))
>>>> -> Index Scan using subclients2_pkey on
>>>> subclients (cost=0.29..8.31 rows=1 width=560)
>>>> Index Cond: (id =
>>>> companies.subclient_id)
>>>> Filter: (((show_3300 IS NOT TRUE)
>>>> AND ((companies.ep_file)::text !~ '_print3300'::text)) OR (show_3300 IS
>>>> TRUE))
>>>> -> Index Scan using temas_pkey on temas
>>>> (cost=0.42..8.44 rows=1 width=108)
>>>> Index Cond: (id = companies.main_tema_id)
>>>> -> Index Scan using domains_pkey on domains
>>>> (cost=0.42..8.44 rows=1 width=874)
>>>> Index Cond: (id = companies.domain_id)
>>>> Filter: ((p_or_d)::text = ANY
>>>> ('{p,d,b}'::text[]))
>>>> -> Index Scan using papers_pkey on papers (cost=0.42..7.93
>>>> rows=1 width=33)
>>>> Index Cond: (id = domains.paper_id)
>>>> -> Index Scan using tematicas_pkey on tematicas (cost=0.14..4.16
>>>> rows=1 width=19)
>>>> Index Cond: (id = domains.tematica_id)
>>>> -> Bitmap Heap Scan on special_values (cost=4.42..8.43 rows=1
>>>> width=2569)
>>>> Recheck Cond: (subclient_id = companies.subclient_id)
>>>> -> Bitmap Index Scan on special_values_subclient_id_idx
>>>> (cost=0.00..4.42 rows=1 width=0)
>>>> Index Cond: (subclient_id = companies.subclient_id)
>>>>
>>>> ya hice un ANALYZE.
>>>> La tabla companies tiene millones de filas.
>>>> La clave primaria de companies es "id"
>>>> No entiendo porque postgres no utiliza primero que nada ese índice para
>>>> reducir las filas de resultado, existe forma de forzar a que lo use? o es
>>>> correcto que no lo use?
>>>>
>>>>
>>>> Desde ya muchas gracias por los comentarios.
>>>>
>>>> Saludos.
>>>>
>>>> Guillermo