在本文中,我们将探讨如何通过使用Explain和Analyze来分析慢查询,以及使用索引来修改和增强查询时间来解决慢查询。

Postgres支持在表上使用各种索引,以加快查询速度。

多列索引

多列B树索引可以与涉及索引的列的任意子集的查询条件下使用。当(最左边)列有约束时,此索引最有效。确切的规则是,前导列上的相等约束,再加上第一列上没有相等约束的任何不相等约束,都将用于限制扫描的索引部分。

Cover索引

包含查询所需的所有列的索引,该索引位于select语句中。

唯一索引

唯一索引是用于强制列值的唯一性或一个以上列的组合值的唯一性的索引。

关于索引的最被误解的概念之一是了解在哪里使用主键,唯一约束或唯一索引。让我们使用一个问题来理解这一点:

问题陈述

我们要求没有重复数据的最高性能。哪种方法更好?主键,唯一约束或唯一索引?

解决方案

注意:多个空值不相等,因此它们不被视为重复记录。

  • 当表中定义了主键和唯一约束时,Postgres会在表中自动创建唯一索引。这样,创建唯一约束将是多余的,并且不必要地创建索引会降低Postgres的性能。根据Postgres产品团队的建议,在表上创建唯一约束,然后就无需在这些列上创建唯一索引。
  • Postgres为定义的主键本身创建一个索引。
  • 当我们创建唯一约束时,Postgres会在后台自动创建索引。

但是,在某些情况下,甚至索引也无法提高性能。一种这样的情况是当我们进行不区分大小写的搜索时。让我们了解的情况下,查询成本之间的差额区分大小写不区分大小写的搜索 我们的计划表。鉴于我们在该列上有一个索引scheme_name。

EXPLAIN ANALYSE SELECT * FROM schemes where scheme_name = 'weekend_scheme'

查询计划| 在方案上使用idx_scheme_name进行索引扫描(成本= 0.28..8.29行= 1宽度= 384)
计划时间:0.155 ms
执行时间:0.063ms

EXPLAIN ANALYSE SELECT * FROM schemes where lower(scheme_name) = 'weekend_scheme'

查询计划| 对方案进行Seq扫描(成本= 0.00..69.00行= 5宽度= 384)
过滤器:(lower((scheme_name):: text)='weekend_scheme':: text)
被过滤器删除的行:999
规划时间:0.119 ms
执行时间:0.721ms

即使我们在处创建了索引scheme_name,该函数lower也会降低性能,因为它会付出额外的努力将所有的值转换scheme_table为小写。

不使用索引(尽管已定义)的情况。

  • LIKE ‘%scheme’永远不会使用索引,但LIKE ‘scheme%’可能会使用索引。
  • where子句中使用的大写/小写函数。

因此,无论何时我们想在where子句中使用函数,我们都可以通过以下方式创建索引来优化查询。CREATE INDEX idx_scheme_name ON schemes (lower(scheme_name))

EXPLAIN ANALYSE SELECT * FROM schemes where lower(scheme_name) = 'weekend_scheme'

查询计划| 方案上的位图堆扫描((cost = 4.32..19.83行= 5宽度= 384))
重新检查条件:(较低((scheme_name):: text)='weekend_scheme':: text)
对块:精确= 1
位图扫描在方案上((cost = 0.00..4.32行= 5宽度= 0))
索引条件:(较低((scheme_name):: text)='weekend_scheme':: text)
计划时间:1.784 ms
执行时间:0.079 ms

部分指数

Postgres支持在表的行子集上建立索引(称为部分索引)。 如果我们要重复分析与给定WHERE子句匹配的行,这通常是索引数据的最佳方法。让我们看看如何使用部分索引来增强Postgres的性能。

问题陈述

我们要返回所有应该在上午11:00之前运行的方案。
EXPLAIN ANALYSE SELECT * FROM schemes WHERE start_time < '10:00:00'

查询计划| 对方案进行Seq扫描(成本= 0.00..66.50行= 9宽度= 23)
过滤器:(start_time 过滤器删除的行:991
规划时间:0.082 ms
执行时间:0.226ms

我们可以在start_time列上创建索引,但是假设我们有一个庞大的数据库,这对于插入,更新和删除可能不是最佳选择。因此,我们创建一个带有条件的索引。当我们从选择查询中知道需要什么时,将使用这种索引。假设我们对所有在10:00:00之前启动的方案进行了大量阅读,而在以后启动时则阅读不多。
CREATE INDEX idx_scheme_name ON schemes start_time WHERE start_time < '11:00:00'

EXPLAIN ANALYSE SELECT * FROM schemes WHERE start_time < '10:00:00'

查询计划| 方案上的位图堆扫描((cost = 4.21..29.30行= 9宽度= 23))
重新检查条件:(start_time 对块:精确= 8
方案上的位图索引扫描((cost = 0.00..4.21行= 9宽度= 0))
索引条件:(start_time 计划时间:1.729 ms
执行时间:0.075 ms

这样可以将执行时间从减少0.226到0.075。

让我们确认我们没有start_time为上午11:00之后的所有方案建立索引。
EXPLAIN ANALYSE SELECT * FROM schemes WHERE start_time >'12:00:00'

查询计划| 对方案进行Seq扫描(成本= 0.00..66.50行= 6宽度= 23)
筛选器:(start_time 筛选器删除的行:993
规划时间:0.101 ms
执行时间:0.228ms

这证明方案表中的部分数据已编制索引,其余数据未编制索引。我们的索引大小非常小,易于维护,有助于维护重新索引的任务。

联接查询计划

优化器需要选择正确的连接时,有在SELECT语句要加入多个表的算法。Postgres根据我们使用的联接类型使用3种不同的联接算法。

嵌套循环:在这里,计划者可以对第一个表中的每个元素使用顺序扫描或索引扫描。当第二个表较小时,计划程序将使用顺序扫描。在顺序扫描和索引扫描之间进行选择的基本逻辑也适用于此。哈希联接:在此算法中,计划程序在联接键上创建较小表的哈希表。然后扫描较大的表,在哈希表中搜索满足连接条件的行。首先,这需要大量内存才能存储哈希表。合并联接:这类似于合并排序算法。计划者在这里对两个要联接的表进行排序。然后并行扫描这些表以找到匹配的值。

EXPLAIN SELECT schemes.rules FROM scheme_rules JOIN schemes ON (scheme_rules.scheme_id = schemes.id ) where scheme_name = 'weekend_scheme';

生产环境中索引的缺点

查找未使用的索引

在大型生产环境中,建议使用未使用的索引,因为索引会占用内存。Postgres Wiki页面详细介绍了如何找到索引摘要,重复索引和索引大小。

CREATE / DROP索引与CREATE / DROP索引并发

在大型数据库中创建和删除索引可能要花费数小时甚至数天,并且该CREATE INDEX命令会阻止对表的所有写操作(它不会阻止读操作,但这仍然不理想)。

但是,与并发创建的索引CREATE INDEX CONCURRENT不会获得针对写入的锁定。在同时创建索引时,Postgres首先扫描表以建立索引,然后再次运行索引以查找自第一遍以来要添加的内容。

同时创建索引也有一个缺点。如果在此过程中出现问题,它不会回滚,并留下无效的索引。可以使用以下查询找到无效的索引。

SELECT * FROM pg_class,pg_index WHERE pg_index.indisvalid = false AND pg_index.indexrelid = pg_class.oid;

重建索引

REINDEX使用存储在索引表中的数据重建索引,从而替换索引的旧副本。如果我们怀疑表上的索引损坏,则可以使用REINDEX INDEX或来重建该索引或表上的所有索引。REINDEX TABLE

REINDEX与删除索引和重新创建索引相似,因为索引内容是从头开始重建的。但是,锁定注意事项却大不相同。REINDEX锁定对索引的父表的写入但不对其进行读取。它还对正在处理的特定索引采取排他锁,这将阻止尝试使用该索引的读取。

另一个选择是同时删除索引并再次创建。

结论

这篇文章旨在概述Postgres如何查询数据库。通过更好地理解查询计划并仔细采取措施(主要是通过索引),我们可以从Postgres数据库中获得最佳性能。

还有其他提高查询性能的方法,但我们会将其保存在以后的文章中。

mongdb 建立了索引唯一性还能重复插入?_「数据库系列」Postgres性能调优——Index...相关推荐

  1. MySql查询优化性能调优,sql性能自测方法,及Mysql索引介绍

    MySql查询优化性能调优,sql性能自测方法,及Mysql索引介绍 前言 一.普通优化加索引(适用于where条件后一个查询条件) 二.组合查询加索引(适用于where条件后多个查询条件) 三.My ...

  2. SQL Server 性能调优3 之索引(Index)的维护

    SQL Server 性能调优3 之索引(Index)的维护 热度1 评论 16 作者:溪溪水草 SQL Server 性能调优3 之索引(Index)的维护 前言 前一篇的文章介绍了通过建立索引来提 ...

  3. 面试官:MySQL索引底层数据结构原理与性能调优,你能回答多少?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新,可以微信搜索[小奇JAVA面试]第一时间阅 ...

  4. ElasticSearch还能性能调优,涨见识、涨见识了!!!

    ElasticSearch 性能调优 作者: 博学谷狂野架构师 GitHub地址:GitHub地址 (有我们精心准备的130本电子书PDF) 概述 性能优化是个涉及面非常广的问题,不同的环境,不同的业 ...

  5. “金三银四”春招指南之“性能调优”:MySQL+Tomcat+JVM,看完还怕面试官的轰炸?

    春招指南之"性能调优":MySQL+Tomcat+JVM,还怕面试官的轰炸? 01 MySQL性能调优 1.1 MySQL性能调优问题有哪些?怎么学? 关于这个,给大家看一份学习大 ...

  6. 【Elasticsearch】索引和查询性能调优的21条建议-以及调优参数

    文章目录 1.概述 1.Elasticsearch部署建议 1.1. 选择合理的硬件配置:尽可能使用 SSD 1.2. 给JVM配置机器一半的内存,但是不建议超过32G 1.3. 规模较大的集群配置专 ...

  7. nginx代理转发_学了三年的性能调优,你还不懂Nginx?怎么跳槽涨薪

    前言 根据 Netcraft 公布的最新的(2019年10月)Web 服务器调查报告,Nginx 的市场份额达到了 32.69%,毫无争议地成为了最流行的 Web 服务器.这主要得益于 Nginx 在 ...

  8. Elasticsearch索引和查询性能调优的21条建议【下】

    Elasticsearch是一款流行的分布式开源搜索和数据分析引擎,具备高性能.易扩展.容错性强等特点.它强化了Apache Lucene的搜索能力,把掌控海量数据索引和查询的方式提升到一个新的层次. ...

  9. 还搞不懂性能调优?让你见识这份《Java性能调优PDF》啃完你就知道多厉害了!

    Java 应用性能优化是一个老生常谈的话题,典型的性能问题如页面响应慢.接口超时,服务器负载高.并发数低,数据库频繁死锁等.尤其是在"糙快猛"的互联网开发模式大行其道的今天,随着系 ...

最新文章

  1. python计算wav的语谱图_Python实现电脑录音(含音频基础知识讲解)
  2. VBS脚本 - 实现一键停止Oracle相关服务
  3. 干货 | VMAF视频质量评估在视频云转码中的应用
  4. Hive中数据的加载和导出
  5. 精确记算程序的运行时间或者某段代码的运行时间
  6. jndi mysql数据库_数据库连接池技术中dbcp、c3p0、jndi
  7. Centos下Yum安装PHP5.5,5.6,7.0
  8. C语言 函数指针 int(*ptr)(int,int)
  9. windows系统下_ffmpeg编译_2011年
  10. VMware HA与VMotion的部署与搭建
  11. Scala学习笔记01:Scala概述、安装配置、简单使用
  12. 在weblogic12c中启动工程报错缺失BeanFactoryAware
  13. 种草 ES2020 八大新功能
  14. javaweb项目JSP网上书店购物电商系统毕业设计
  15. 你还记得大明湖畔的我吗?来自黑莓的呼喊
  16. 曾经跨过山和大海的百度AI技术汇,跨进北工大!
  17. CDH添加ELASTICSEARCH服务elasticsearch-cdh-parcels
  18. 国内外PaaS案例解析、赛道、趋势
  19. python 列表查重_用python对excel查重
  20. 四缸汽油机曲轴及凸轮轴信号生成(基于STM32)

热门文章

  1. 报错显示从客户端检测到有潜在危险的Request.Form 值
  2. 在C#项目中使用SQLite(环境安装问题)
  3. vs中c#的项目配置,平台配置
  4. C# 中的回车换行符 表示
  5. h5 app title隐藏_荒岛求生H5:有难度的文字冒险生存游戏,你能生存多久?
  6. 需要额外端口信息_NR逻辑天线端口介绍
  7. python 倒叙 数组_Python函数合集:68个内置函数请收好!
  8. win10下安装SQLServer2000
  9. Buildroot构建指南--Overview
  10. Android开发之带行号显示的Log工具类