该系统是PG-Windows,带有8 GB RAM Windows 7笔记本电脑和SSD.
我分配了2048MB作为shared_buffers,256MB作为temp_buffers,128MB作为work_mem.
我对单个表执行多次单个查询 – 希望表保留在RAM中(因此上面的参数).
但是,虽然我看到执行期间内存使用量激增(大约200 MB),但我没有看到内存消耗至少保持在500 MB(数据保留在内存中).运行的所有postgres exe在任务管理器中显示2-6 MB大小.因此,我怀疑LRU不会将数据保存在内存中.
平均查询执行时间大约是2秒(非常简单的单表查询)…但我需要将其降低到大约10-20毫秒甚至更小(如果可能的话),纯粹因为有太多次,同样的要执行并且只能通过将内容保存在内存中来实现.
有什么建议?
问候,
卡皮尔
这是因为Postgresql依赖于来自操作系统缓冲区缓存的缓冲读取.简单来说,当Postgresql执行read()时,操作系统会查看所请求的块是否缓存在用于磁盘缓存的“空闲”RAM中.如果块在缓存中,则OS几乎立即返回.如果块不在缓存中,则OS从磁盘读取它,将其添加到磁盘缓存中,然后返回该块.后续读取将从缓存中获取它,除非它被其他块从缓存中移位.
这意味着如果你有足够的可用内存来使整个数据库适合“免费”操作系统内存,你就不会倾向于在磁盘上进行读取.
根据操作系统,磁盘写入的行为可能不同. Linux将回写缓存“脏”缓冲区,并且即使它们已被写入,仍将从缓存中返回块.它会将这些写回磁盘,除非被强制用fsync()立即写入,因为Pg在COMMIT时使用.当它这样做时,它会标记缓存的块清理,但不会刷新它们.我不知道Windows在这里的表现如何.
关键是Postgresql可以完全用RAM运行1GB数据库,即使没有Postgresql进程似乎使用了大量的RAM.如果shared_buffers太高,则会导致双缓存,并且可以减少OS可用于缓存块的RAM量.
由于Pg依赖于OS缓存,因此很难确切地看到RAM中缓存了什么.这就是为什么我把你推荐给pg_fincore
.
如果你在Windows上并且这不起作用,你真的只需要依赖于观察磁盘活动.性能监视器是否显示大量未缓存的磁盘读取?操作系统内存监控是否显示操作系统中用于磁盘缓存的大量内存?
确保effective_cache_size正确反映了用于磁盘缓存的RAM.它将帮助Postgresql选择合适的查询计划.
在没有明显证据的情况下,您正在假设您正在经历的查询性能由磁盘读取延迟来解释,并且可以通过内存中缓存来改进它.根本不是这种情况.您需要查看解释分析输出和系统性能指标,以了解正在发生的情况.