Performance 选择8000万行花费的时间太长

Performance 选择8000万行花费的时间太长,performance,postgresql,postgresql-performance,Performance,Postgresql,Postgresql Performance,表格: Table "public.hugetable" Column | Type | Modifiers | Storage | Description ---------+-----------------------+-----------+----------+------------- reqid | character varying(15) | | extended

表格:

                       Table "public.hugetable"
 Column  |         Type          | Modifiers | Storage  | Description 
---------+-----------------------+-----------+----------+-------------
 reqid   | character varying(15) |           | extended | 
 browser | character varying(15) |           | extended | 
 a       | smallint              |           | plain    | 
 b       | smallint              |           | plain    | 
 metarr  | smallint[]            |           | extended | 
db.m3.xlarge
Type:Type   Standard - Current Generation
vCPU:Number of virtual cores    4 vCPU
Memory: 15 GiB
行数:8000万

索引:无

解释:

testdb=> EXPLAIN (ANALYZE,BUFFERS) select b from hugetable;
                                                         QUERY PLAN                                                         
----------------------------------------------------------------------------------------------------------------------------
 Seq Scan on hugetable  (cost=0.00..6514286.08 rows=80000008 width=2) (actual time=0.009..598004.456 rows=80000000 loops=1)
   Buffers: shared hit=472831 read=5241455
 Total runtime: 674134.766 ms
metarr smallint[]
包含250个元素

使用
select b from hugetable,其中a=someval
select metric[199]from hugetable

服务器规格:

                       Table "public.hugetable"
 Column  |         Type          | Modifiers | Storage  | Description 
---------+-----------------------+-----------+----------+-------------
 reqid   | character varying(15) |           | extended | 
 browser | character varying(15) |           | extended | 
 a       | smallint              |           | plain    | 
 b       | smallint              |           | plain    | 
 metarr  | smallint[]            |           | extended | 
db.m3.xlarge
Type:Type   Standard - Current Generation
vCPU:Number of virtual cores    4 vCPU
Memory: 15 GiB

我从未使用过如此大的数据集,因此我不确定10分钟对于这种查询是否正常


实际上,将有另一列(datetime)。该表将在一整天内包含约8000万条记录,查询将始终为
SELECT metarr[someindex],其中datetimecolumn>something和datetimecolumn磁盘上的表比RAM大。因此,该表不能完全缓存在RAM中。增加内存大小以适合您的工作集。这将删除所有IO

只为您需要的列编制索引。这样,PostgreSQL就可以只扫描索引,扫描更少的数据。这将减少工作集


您现在可能在数据库和应用程序之间的网络上遇到瓶颈。

如何提高数据库查询性能

  • 为用于比较的列编制索引(在两个示例中,例如:date列都应编制索引)

  • 水平分区(shard)将工作台分成几个块(例如:每日旋转),并将每个块放在不同的机器上

  • 通过跨多台计算机复制数据库分区来复制数据库。这在您的情况下不会有多大帮助,除非您有具有不同标准的并发查询

  • 使用高IOPS SSD驱动器(AWS称之为配置IO)

  • 对于日期使用datetime类型,它比int具有更好的性能

  • 使用memcached、redis等缓存结果,以便更快地检索(如果同一查询将运行多次)


  • 索引表将大大缩短查询时间。索引表的依据是什么?如果没有索引,600秒是合理的时间吗?您的查询要求所有数据,所以这就是您得到的。然后这取决于系统的性能,速度有多快。考虑到$$不是一个问题,我需要增加什么特定属性才能获得更好的性能?眼压@danmullen胡说八道-获取完整表内容的最快方法几乎总是seqscan,因此这里给出的示例根本不会受益于索引。您是对的,“实际上…”部分将受益于
    datetimecolumn
    上的btree索引。