Jeff
Jeff

Reputation: 1800

Slow running Postgres query

I have this query that takes a very long time on my database. This SQL is generated from an ORM (Hibernate) inside of an application. I don't have access to the source code.

I was wondering if anyone can take a look at the following ANALYZE EXPLAIN output and suggest any Postgres tweaks I can make.

I don't know where to start or how to tune my database to service this query.

The query looks like this

select 
    resourceta0_.RES_ID as col_0_0_ 
from
    HFJ_RESOURCE resourceta0_ 
    left outer join HFJ_RES_LINK myresource1_ on resourceta0_.RES_ID = myresource1_.TARGET_RESOURCE_ID 
    left outer join HFJ_SPIDX_DATE myparamsda2_ on resourceta0_.RES_ID = myparamsda2_.RES_ID 
    left outer join HFJ_SPIDX_TOKEN myparamsto3_ on resourceta0_.RES_ID = myparamsto3_.RES_ID 
where 
    (myresource1_.SRC_RESOURCE_ID in ('4954427' ... many more))
    and myparamsda2_.HASH_IDENTITY=`5247847184787287691` and 
(myparamsda2_.SP_VALUE_LOW>='1950-07-01 11:30:00' or myparamsda2_.SP_VALUE_HIGH>='1950-07-01 11:30:00') 
    and myparamsda2_.HASH_IDENTITY='5247847184787287691' 
    and (myparamsda2_.SP_VALUE_LOW<='1960-06-30 12:29:59.999' or myparamsda2_.SP_VALUE_HIGH<='1960-06-30 12:29:59.999') 
    and (myparamsto3_.HASH_VALUE in ('-5305902187566578701')) 
limit '500'

And the execution plan looks like this: https://explain.depesz.com/s/EJgOq

Edit - updated to add the depesz link. Edit 2 - added more information about the query.

Upvotes: 1

Views: 373

Answers (1)

Laurenz Albe
Laurenz Albe

Reputation: 248295

The cause for the slowness are the bad row count estimates which make PostgreSQL choose a nested loop join. Almost all your time is spent in the index scan on hfj_res_link, which is repeated 1113 times.

My first attempt would be to ANALYZE hfj_spidx_date and see if that helps. If yes, make sure that autoanalyze treats that table more frequently.

The next attempt would be to

SET default_statistics_target = 1000;

and then ANALYZE as above. If that helps, use ALTER TABLE to increase the STATISTICS on the hash_identity and sp_value_high columns.

If that doesn't help either, and you have a recent version of PostgreSQL, you could try extended statistics:

CREATE STATISTICS myparamsda2_stats (dependencies)
   ON hash_identity, sp_value_high FROM hfj_spidx_date;

Then ANALYZE the table again and see if that helps.

If all that doesn't help, and you cannot get the estimates correct, you have to try a different angle:

CREATE INDEX ON hfj_res_link (target_resource_id, src_resource_id);

That should speed up the index scan considerably and give you good response times.

Finally, if none of the above has any effect, you could use the cruse measure of disallowing nested loop joins for this query:

BEGIN;
SET LOCAL enable_nestloop = off;
SELECT /* your query goes here */;
COMMIT;

Upvotes: 2

Related Questions