创建包含10个列(c01 - c10)的表my_table,用如下语句创建2个索引,并向表中插入6w条记录。这6w条记录的c01列,全部都是2017年04月21日的数据。

CREATE INDEX my_table_index1ON my_tableUSING btree(c05, c01, c02)
TABLESPACE smart_history_index;CREATE INDEX my_table_index2ON my_tableUSING btree(c01, c02, c03, c04, c05)
TABLESPACE smart_history_index;

使用以下SQL1语句查询,查询时间为2分钟。
SQL1:

select * from my_table t1
where (select count(*) from my_table t2 where
((t1.c01 = t2.c01 ) or (t1.c01 is null and t2.c01 is null)) and
((t1.c02 = t2.c02 ) or (t1.c02 is null and t2.c02 is null)) and
((t1.c03 = t2.c03 ) or (t1.c03 is null and t2.c03 is null)) and
((t1.c04 = t2.c04 ) or (t1.c04 is null and t2.c04 is null)) and
((t1.c05 = t2.c05 ) or (t1.c05 is null and t2.c05 is null)) and
((t1.c06 = t2.c06 ) or (t1.c06 is null and t2.c06 is null)) and
((t1.c07 = t2.c07 ) or (t1.c07 is null and t2.c07 is null)) and
((t1.c08 = t2.c08 ) or (t1.c08 is null and t2.c08 is null)) and
((t1.c09 = t2.c09 ) or (t1.c09 is null and t2.c09 is null)) and
((t1.c10 = t2.c10 ) or (t1.c10 is null and t2.c10 is null))
)>1;

使用以下SQL2语句查询,查询时间为2.8秒。
SQL2:

select * from my_table t1
where (select count(*) from my_table t2 where
((t1.c01 = t2.c01 ) or (t1.c01 is null and t2.c01 is null)) and
((t1.c02 = t2.c02 ) or (t1.c02 is null and t2.c02 is null)) and
((t1.c03 = t2.c03 ) or (t1.c03 is null and t2.c03 is null)) and
((t1.c04 = t2.c04 ) or (t1.c04 is null and t2.c04 is null)) and
((t1.c05 = t2.c05 ) or (t1.c05 is null and t2.c05 is null)) and
((t1.c06 = t2.c06 ) or (t1.c06 is null and t2.c06 is null)) and
((t1.c07 = t2.c07 ) or (t1.c07 is null and t2.c07 is null)) and
((t1.c08 = t2.c08 ) or (t1.c08 is null and t2.c08 is null)) and
((t1.c09 = t2.c09 ) or (t1.c09 is null and t2.c09 is null)) and
((t1.c10 = t2.c10 ) or (t1.c10 is null and t2.c10 is null)) and
(c01 >= '2017-04-20 00:00:00' and c01 < '2017-04-21 00:00:00')
)>1 and (c01 >= '2017-04-20 00:00:00' and c01 < '2017-04-21 00:00:00');

虽然SQL2最后对于c01列的where条件并为实质上减少过滤出的数据量。但是能够显著的提高查询效率(60倍),进一步使用以下SQL3语句监视索引使用情况发现,SQL2只调用了my_table_index2,而SQL1既调用了my_table_index1也调用了my_table_index2。
SQL3:

select
relname, indexrelname, idx_scan, idx_tup_read, idx_tup_fetch
from pg_stat_user_indexes
where relname = 'my_table'
order by idx_scan asc, idx_tup_read asc, idx_tup_fetch asc;

显然my_table_index2肯定比my_table_index1的辨识度更高。之所以SQL优化解析器会做出这样的选择,猜测可能是因为my_table_index2中列c01处于第一个的位置,而SQL2最后的c01查询条件刚好暗示强化了解释器去选择my_table_index2。
在此基础上我进行了进一步的实验:如果drop掉my_table_index1只保留my_table_index2,则无论是SQL1还是SQL2都能达到大约2.8秒的查询速度;如果drop掉my_table_index2只保留my_table_index1,则无论是SQL1还是SQL2都需要2分钟才能完成查询;当然my_table_index1也并不是一无是处,如果将两个索引全部drop掉,那么做一次查询(全表扫描)大约需要10分钟。

最后说两点启示:
1.索引不能随便建,如果建的不好,不仅影响插入效率,也会影响查询效率。
2.SQL语句优化之路,任重而道远。

PostgreSQL索引探究相关推荐

  1. 资源放送丨《 MySQL中的索引探究 - 2020云和恩墨大讲堂》PPT视频

    前段时间,墨天轮邀请到云和恩墨应用架构产品部总经理 巩飞 分享了直播<MySQL中的索引探究>,在这里我们共享一下PPT和视频,供大家参考学习. 本次分享讲述MySQL的索引原理,不同存储 ...

  2. 直播预告丨MySQL中的索引探究

    MySQL中的索引探究 - 08/05 本次分享讲述MySQL的索引原理,不同存储引擎对索引的支持情况.同时探究大家普遍关心的问题:MySQL在哪些操作中会用到索引?InnoDB引擎对索引做了哪些扩展 ...

  3. postgresql索引_PostgreSQL中的索引— 10(Bloom)

    postgresql索引 indexing engine and the interface of access methods, as well as 索引引擎和访问方法的接口,以及hash ind ...

  4. PostgreSQL索引膨胀

    PostgreSQL索引膨胀 最后编辑时间:2022年1月23日00:07:27 通常是因为数据乱序写入导致的,索引页中的数据是有序的,而索引字段乱序写入,会导致索引频繁分裂,使得索引页并不是百分百填 ...

  5. postgresql索引_PostgreSQL中的索引— 8(RUM)

    postgresql索引 indexing engine, the interface of access methods, and main access methods, such as: 索引引 ...

  6. postgresql索引_PostgreSQL中的索引— 6(SP-GiST)

    postgresql索引 indexing engine, 索引引擎 , the interface of access methods, and three methods: 访问方法的接口以及三种 ...

  7. PostgreSQL索引介绍

    梦中彩虹 博客园 首页 新随笔 联系 管理 随笔 - 131  文章 - 1  评论 - 14 PostgreSQL索引介绍 INDEX 索引是增强数据库性能的常用方法.索引使得数据库在查找和检索数据 ...

  8. 掌握查询利器 深入理解PostgreSQL索引原理与优化

    文章目录 一.前言 1.1 PostgreSQL索引的重要性 1.2 本文的结构和目的 二.索引概述 2.1 什么是索引 2.2 为什么要使用索引 2.3 索引如何工作 三.索引类型 3.1 B-tr ...

  9. PostgreSQL索引页

    本页目的,是起到索引其他所有本人所写文档的作用: 分类一:PostgreSQL基础知识与基本操作--------------------  PostgreSQL基础知识与基本操作索引页 分类二:Pos ...

最新文章

  1. 垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?...
  2. Fragment为什么须要无参构造方法
  3. 【js】内置对象String的常用方法
  4. 实战证明LINUX系统下密钥对验证的安全性
  5. 创业5年,我有5点关于人的思考
  6. 【JavaSE05】Java中方法与重载、递归
  7. 阅读笔记一之《软件需求与分析》
  8. python与golang_Golang与python线程详解及简单实例
  9. [机器学习-Sklearn]函数sklearn.feature_extraction.DictVectorizer理解与总结
  10. eleTree树形插件引入
  11. leetcode两数之和,三数之和,四数之和问题
  12. 深入剖析SolrCloud(四)
  13. vc ++ 如何做界面开发?
  14. 安全测试者偏爱的安全测试工具
  15. 浏览器份额及其历史以及内核变迁总结
  16. 多节点什么网络取得技术性突破_我国学者研究“多节点量子网络”取得基础性突破...
  17. ABC182 E - Akari(扫描)
  18. C++ 的 Copy Elision
  19. 表格中自动布局注意和使用自动计算行高
  20. 什么样的自学Java网站才适合学习者?

热门文章

  1. 11g 64位部分安装过程
  2. 深度解析iPhone Category用法
  3. 如何保证数据库服务器的安全性
  4. cola-ui的使用
  5. 请写出一段Python代码实现删除一个list里面的重复元素
  6. 【bzoj4939】【YNOI2016】掉进兔子洞(莫队)
  7. git学习创建项目仓库
  8. 函数和常用模块【day04】: 总结(十二)
  9. BestCoder25 1001.Harry and Magical Computer(hdu 5154) 解题报告
  10. 关于在安装ASP.NET Forum中出现的无法排序的问题.