此查询对我的数据库需要很长时间。该SQL是从应用程序内部的ORM(休眠)生成的。我无权访问源代码。
我想知道是否有人可以看看下面的ANALYZE EXPLAIN
输出并提出我可以做的Postgres调整。
我不知道从哪里开始或如何调整数据库来为该查询服务。
查询看起来像这样
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'
执行计划如下:https://explain.depesz.com/s/EJgOq
编辑-更新以添加depesz链接。 编辑2-添加了有关查询的更多信息。
答案 0 :(得分:2)
速度变慢的原因是错误的行计数估计,这使PostgreSQL选择了嵌套循环联接。您几乎所有的时间都花在hfj_res_link
的索引扫描上,重复1113次。
我的第一个尝试是去ANALYZE hfj_spidx_date
,看看是否有帮助。如果是,请确保自动分析会更频繁地处理该表。
下一个尝试将是
SET default_statistics_target = 1000;
,然后如上所述的ANALYZE
。如果有帮助,请使用ALTER TABLE
增加STATISTICS
和hash_identity
列上的sp_value_high
。
如果这也无济于事,并且您有PostgreSQL的最新版本,则可以尝试扩展统计信息:
CREATE STATISTICS myparamsda2_stats (dependencies)
ON hash_identity, sp_value_high FROM hfj_spidx_date;
然后再次ANALYZE
该表,看看是否有帮助。
如果所有这些都无济于事,并且您无法正确获得估算值,则必须尝试使用其他角度:
CREATE INDEX ON hfj_res_link (target_resource_id, src_resource_id);
那将大大加快索引扫描的速度,并为您提供良好的响应时间。
最后,如果以上方法均无效,则可以使用禁止嵌套嵌套连接的严厉措施:
BEGIN;
SET LOCAL enable_nestloop = off;
SELECT /* your query goes here */;
COMMIT;