有两台结构和配置相同的数据库机器,具有以下特点。数据库的结构和内容也相同。几乎 99% 的查询在新机器上的性能更好,只有少数是急剧下降的。试图缩小调查范围,我终于发现只有一个 KNN(K Nearest Neighbour)查询是真正的罪犯。以下是有关“地图”表(约 820k 行)的相关信息:
\d maps
Table "maps"
Column | Type | Collation | Nullable |
------------+-------------------+-----------+----------
id | integer | | not null |
strada | character varying | | |
(...)
the_geom | geography | | |
concat_all | character varying | | |
(...)
Indexes:
"pk_maps" PRIMARY KEY, btree (id), tablespace "maps_idx"
"ggx_maps_the_geom" gist (the_geom) WITH (fillfactor='100', buffering='on'), tablespace "maps_idx"
"ix_maps_strada" hash (strada), tablespace "maps_idx"
Tablespace: "maps_data"
在下面的“解释分析”调查中,我使用了一个“点”进行测试(实际上除了一个长的不相关的字符串,为了方便起见,只是用“点”替换并由“缓冲区”中的 st_buffer 转换)
EXPLAIN ANALYZE
SELECT *
FROM maps m
WHERE st_buffer('point'::GEOGRAPHY,100::DOUBLE PRECISION) && m.the_geom
ORDER BY m.the_geom<->'point'::GEOGRAPHY
LIMIT 1;
以下是实际的机器响应:
(机器#1:16CPU | 64GB RAM | Linux Ubuntu 16.04.7 LTS | PostgreSQL 9.6.21)
Limit (cost=0.29..1.96 rows=1 width=711) (actual time=1.306..1.306 rows=1 loops=1)
-> Index Scan using ggx_maps_the_geom on maps m (cost=0.29..1.96 rows=1 width=711) (actual time=1.305..1.305 rows=1 loops=1)
Index Cond: ('buffer'::geography && the_geom)
Order By: (the_geom <-> 'point'::geography)
Planning time: 2.977 ms
Execution time: 1.480 ms
(6 rows)
Time: **6.885 ms**
(机器#2:16CPU | 64GB RAM | Linux Ubuntu 20.04.2 LTS | PostgreSQL 13.2)
Limit (cost=0.29..1.96 rows=1 width=692) (actual time=66.421..66.422 rows=1 loops=1)
-> Index Scan using ggx_maps_the_geom on maps m (cost=0.29..1.96 rows=1 width=692) (actual time=66.420..66.420 rows=1 loops=1)
Index Cond: (the_geom && 'buffer'::geography)
Order By: (the_geom <-> 'point'::geography)
Planning Time: 20.289 ms
Execution Time: 66.477 ms
(6 rows)
Time: **88.116 ms** (!)
可以看出,机器#2 的性能急剧下降,尽管事实上这两台机器在所有方面都是相同的,包括配置也是如此。有谁知道如何处理这个问题?要检查什么以获得一些线索?