postgresql - 优化拥有近 1.5 亿条记录的 Postgres DB

标签 postgresql azure query-optimization azure-postgresql

我正在使用 Azure Postgress DB 存储大约 1.5 亿条记录。 DB 的规范为:160GB 存储和约 4GB RAM。加载到数据库中时,数据集约为 80GB。数据集不会增长,但会保持在 80 - 85 GB 左右。

这是表定义:

CREATE TABLE properties(
    PropertyId bigint,
    Address text,
    Latitude double precision,
    Longitude double precision,
    Rooms int,
    BathRooms int
)

还有一些列

大多数查询基于以下 4 个字段:

Address (text) 
Longitude (double)
Latitude (double)
PropertyId (big int)

我已经在所有这些字段上实现了索引。对于地址 - GIN,其他 B 树。

CREATE INDEX address_idx ON properties USING GIN (Address gin_trgm_ops);
CREATE INDEX propertyid_idx ON properties(PropertyId);
CREATE INDEX latitude_idx ON properties(Latitude);
CREATE INDEX longitude_idx ON properties(Longitude);

但问题仍然是查询速度很慢,即

select * from my_table 
where Latitude between x and y
and Longitude between p and q
and address like '%address%';

需要几分钟...

我使用解释分析来分析查询,这表明查询确实使用了索引。

"Bitmap Heap Scan on properties  (cost=34256.04..34901.54 rows=10 width=561) (actual time=24664.562..32007.752 rows=35 loops=1)"
"  Recheck Cond: ((Address ~~ '%3365%'::text) AND (Longitude >= '-90.5'::double precision) AND (Longitude <= '-90'::double precision))"
"  Rows Removed by Index Recheck: 1123"
"  Filter: ((propertylatitude >= '38'::double precision) AND (propertylatitude <= '39'::double precision))"
"  Rows Removed by Filter: 64"
"  Heap Blocks: exact=1213"
"  Buffers: shared hit=181 read=6478"
"  I/O Timings: read=31160.388"
"  ->  BitmapAnd  (cost=34256.04..34256.04 rows=161 width=0) (actual time=24660.058..24660.059 rows=0 loops=1)"
"        Buffers: shared hit=169 read=5277"
"        I/O Timings: read=23836.224"
"        ->  Bitmap Index Scan on address_idx  (cost=0.00..135.75 rows=12233 width=0) (actual time=6892.077..6892.077 rows=12973 loops=1)"
"              Index Cond: (Address ~~ '%3365%'::text)"
"              Buffers: shared hit=168 read=321"
"              I/O Timings: read=6815.544"
"        ->  Bitmap Index Scan on longitude_idx  (cost=0.00..34120.04 rows=1627147 width=0) (actual time=17763.265..17763.265 rows=1812752 loops=1)"
"              Index Cond: ((Longitude >= '-90.5'::double precision) AND (Longitude <= '-90'::double precision))"
"              Buffers: shared hit=1 read=4956"
"              I/O Timings: read=17020.681"
"Planning Time: 0.267 ms"
"Execution Time: 32008.085 ms"

所以我的问题是,

  1. 有什么方法可以提高性能(SQL 方面)?不同的索引算法或策略?
  2. 在计算给定数据大小的内存和存储要求时是否有经验法则?要在 2 秒内获得结果,最低的足够硬件要求是多少?

最佳答案

查询使用索引并且估计结果很好。

你的时间几乎全部花在了 I/O 上,而你的 I/O 速度约为每秒 2MB,这很糟糕。也许您的 I/O 子系统重载;您可能想检查一下。

使用这种存储方式,您唯一的机会是将整个表及其索引缓存在 RAM 中。或者您可以获得更快的存储。

关于postgresql - 优化拥有近 1.5 亿条记录的 Postgres DB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69085509/

相关文章:

mysql - 将数据从 SQL Server/PostgreSQL 移动到 MySQL

Azure access_token 包含我认为会在 id_token 中的信息,反之亦然

azure - 用于单点登录的 msal-Angular

mysql - NOT IN 子查询与 ON != 操作

oracle - 在Oracle中使用ANSI数据类型是否有性能损失?

postgresql - pg_dump 9.0 到 pg_restore 8.3

postgresql - Postgres SSL 错误

postgresql - 获取我的 postgresql 数据库版本?

azure - gitlab 管道到 azure 静态 Web 应用程序似乎不起作用

mysql - 检查mysql是否有索引null