Reputation: 1800
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
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