Warm tip: This article is reproduced from serverfault.com, please click

sql-查询可能很慢?

(sql - Query is possibly slow?)

发布于 2020-11-27 23:05:31

我不确定postgres有什么正常现象。

在托管VMpostgres实例上运行此程序Google Cloud,我尝试甚至对4GBRam和4cpu进行调整,但实际上没有任何区别。

下面的查询每次运行都需要200-300ms的时间,这在我为每个查询循环时加起来country_id,因此这可能从我的JavaScript代码中被调用了50次:

select
 c.community_id,
 c.name
 from community c
 join community_location cl on cl.community_id = c.community_id
 join location l on cl.location_id = l.location_id
where l.country_id = 60

执行时间223ms

表格本身很小,社区或位置中的行不超过200行。

花费这么长时间是合理的吗?还是这只是格式错误的查询?

这是它的解释过程:

"Nested Loop  (cost=1.79..5.54 rows=4 width=40)"
"  ->  Hash Join  (cost=1.65..3.29 rows=4 width=4)"
"        Hash Cond: (cl.location_id = l.location_id)"
"        ->  Seq Scan on community_location cl  (cost=0.00..1.50 rows=50 width=8)"
"        ->  Hash  (cost=1.60..1.60 rows=4 width=4)"
"              ->  Seq Scan on location l  (cost=0.00..1.60 rows=4 width=4)"
"                    Filter: (country_id = 60)"
"  ->  Index Scan using community_pkey on community c  (cost=0.14..0.56 rows=1 width=40)"
"        Index Cond: (community_id = cl.community_id)"

我尝试过也运行此查询,而不是每次都从我的JS代码中调用它,而只是尝试对IN我的JavaScript循环使用所有国家/地区ID进行硬编码,但是当我直接运行查询时,基本上速度是相同的IN

select
 c.community_id,
 c.name
 from community c
 join community_location cl on cl.community_id = c.community_id
 join location l on cl.location_id = l.location_id
where l.country_id in (
    6,
    8,
    9,
    26,
    23,
    32,
    35,
    44,
    60,
    64,
    66,
    77,
    81,
    83,
    93,
    116,
    123,
    131,
    137,
    138,
    142,
    153,
    164,
    169,
    178,
    184,
    185
)

执行时间232ms

执行结果:

"Hash Join  (cost=5.57..9.91 rows=33 width=40)"
"  Hash Cond: (c.community_id = cl.community_id)"
"  ->  Seq Scan on community c  (cost=0.00..3.74 rows=74 width=40)"
"  ->  Hash  (cost=5.15..5.15 rows=33 width=4)"
"        ->  Hash Join  (cost=3.51..5.15 rows=33 width=4)"
"              Hash Cond: (cl.location_id = l.location_id)"
"              ->  Seq Scan on community_location cl  (cost=0.00..1.50 rows=50 width=8)"
"              ->  Hash  (cost=3.10..3.10 rows=33 width=4)"
"                    ->  Seq Scan on location l  (cost=0.00..3.10 rows=33 width=4)"
"                          Filter: (country_id = ANY ('{6,8,9,26,23,32,35,44,60,64,66,77,81,83,93,116,123,131,137,138,142,153,164,169,178,184,185}'::integer[]))"
Questioner
PositiveGuy
Viewed
0
Gordon Linoff 2020-11-28 09:53:19

对于此查询:

select c.community_id, c.name
from community c join
     community_location cl
     on cl.community_id = c.community_id join
     location l
     on cl.location_id = l.location_id
where l.country_id = 60;

你需要以下索引:

  • location(country_id, location_id)
  • community_location(location_id, community_id)
  • community(community_id)