GIN(Generalized Inverted Index, 通用倒排索引) 是一个存储对(key, posting list)集合的索引结构,其中key是一个键值,而posting list 是一组出现过key的位置。如(‘hello', '14:2 23:4')中,表示hello在14:2和23:4这两个位置出现过,在PG中这些位置实际上就是元组的tid(行号,包括数据块ID(32bit),以及item point(16 bit) )。

在表中的每一个属性,在建立索引时,都可能会被解析为多个键值,所以同一个元组的tid可能会出现在多个key的posting list中。

通过这种索引结构可以快速的查找到包含指定关键字的元组,因此GIN索引特别适用于多值类型的元素搜索,比如支持全文搜索,数组中元素的搜索,而PG的GIN索引模块最初也是为了支持全文搜索而开发的。

说到这里,你可能会觉得GIN的结构有点像b+tree,包括KEY和对应的值(posting list)。别急,请继续往下看。

  • receivers跟reads字段都是数组,使用any函数来查找是个性能差的事情并且加了gin索引CBO也不会用上,使用了2295.317 ms
explain(analyze,verbose,buffers,costs,timing)
SELECT
"msgId",
"sender",
"contentType",
"content",
"expiresIn",
"timestamp",
"sessionType",
"sessionId",
"isRescission",
"isOncePush",
CAST ( "extensions" AS VARCHAR ),
NULL AS "receivers",
NULL AS "reads"
FROM
"表"
WHERE
NOT "isRescission"
AND 7189526 = ANY ( "receivers" )
AND NOT 7189526 = ANY ("reads");
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on public."表" (cost=0.00..140829.79 rows=79282 width=206) (actual time=191.069..2295.282 rows=1 loops=1)
Output: "msgId", sender, "contentType", content, "expiresIn", "timestamp", "sessionType", "sessionId", "isRescission", "isOncePush", (extensions)::character varying, NULL::unknown, NULL::unknown
Filter: ((NOT "表"."isRescission") AND (7189526 = ANY ("表".receivers)) AND (7189526 <> ALL ("表".reads)))
Rows Removed by Filter: 1776067
Buffers: shared hit=79270
Planning time: 0.092 ms
Execution time: 2295.317 ms
  • 对表添加gin索引并改写语句达到性能优化目的
CREATE INDEX idxrgin1 on "OnceMessages_test" USING GIN ("receivers");

CREATE INDEX idxrgin2 on "OnceMessages_test" USING GIN ("reads");
改写成array函数 , @>包含, 并强制类型转换::bigint 

explain(analyze,verbose,buffers,costs,timing)
SELECT "msgId",
"sender",
"contentType",
"content",
"expiresIn",
"timestamp",
"sessionType",
"sessionId",
"isRescission",
"isOncePush",
CAST ( "extensions" AS VARCHAR ),
NULL AS "receivers",
NULL AS "reads" FROM "public"."表_test" where "receivers" @> ARRAY[7189526::bigint] and NOT "isRescission"
and "reads" @>ARRAY[7189526::bigint] = 'f' Bitmap Heap Scan on public."表_test" (cost=18.98..1484.00 rows=375 width=207) (actual time=0.110..0.110 rows=1 loops=1)
Output: "msgId", sender, "contentType", content, "expiresIn", "timestamp", "sessionType", "sessionId", "isRescission", "isOncePush", (extensions)::character varying, NULL::unknown, NULL::unknown
Recheck Cond: ("表_test".receivers @> '{7189526}'::bigint[])
Filter: ((NOT "表_test"."isRescission") AND (NOT ("表_test".reads @> '{7189526}'::bigint[])))
Rows Removed by Filter: 2
Heap Blocks: exact=3
Buffers: shared hit=1 read=6
I/O Timings: read=0.032
-> Bitmap Index Scan on idxrgin1 (cost=0.00..18.89 rows=385 width=0) (actual time=0.057..0.057 rows=3 loops=1)
Index Cond: ("表_test".receivers @> '{7189526}'::bigint[])
Buffers: shared hit=1 read=3
I/O Timings: read=0.016
Planning time: 0.299 ms
Execution time: 0.149 ms
  • 改写之后性能达到 0.149ms , , 函数不能乱用,随便用上性能会不会更慢也不知道,要多看手册, 中国普遍程序员都是这种想用就用的模式,跟国外完全不一样的先理解再使用

   否则研发思维只会越来越落后!

CREATE INDEX idxrgin1 on "OnceMessages_test" USING GIN ("receivers");

CREATE INDEX idxrgin2 on "OnceMessages_test" USING GIN ("reads");

gin索引优化实例1的更多相关文章

  1. MySQL索引优化实例说明

    下面分别创建三张表,并分别插入1W条简单的数据用来测试,详情如下: [1] test_a 有主键但无索引   CREATE TABLE `test_a` (   `id` int(10) unsign ...

  2. MySql 索引优化实例

    查询语句 SELECT customer_id,title,content FROM `product_comment` WHERE audit_status=1 AND product_id=199 ...

  3. mysql 优化实例之索引创建

    mysql 优化实例之索引创建 优化前: pt-query-degist分析结果: # Query 23: 0.00 QPS, 0.00x concurrency, ID 0x78761E301CC7 ...

  4. 浅谈postgresql的GIN索引(通用倒排索引)

    1.倒排索引原理 倒排索引来源于搜索引擎的技术,可以说是搜索引擎的基石.正是有了倒排索引技术,搜索引擎才能有效率的进行数据库查找.删除等操作.在详细说明倒排索引之前,我们说一下与之相关的正排索引并与之 ...

  5. MySQL优化实例

    这周就要从泰笛离职了,在公司内部的wiki上,根据公司实际的项目,写了一些mysql的优化方法,供小组里的小伙伴参考下,没想到大家的热情很高,还专门搞了个ppt讲解了一下. 举了三个大家很容易犯错的地 ...

  6. mysql sql优化实例

    mysql sql优化实例 优化前: pt-query-degist分析结果: # Query 3: 0.00 QPS, 0.00x concurrency, ID 0xDC6E62FA021C85B ...

  7. SQL 查询优化 索引优化

    sql语句优化 性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的 ...

  8. MySQL高级第二章——索引优化分析

    一.SQL性能下降原因 1.等待时间长?执行时间长? 可能原因: 查询语句写的不行 索引失效(单值索引.复合索引) CREATE INDEX index_user_name ON user(name) ...

  9. MySQL高级学习笔记(四):索引优化分析

    文章目录 性能下降 SQL慢 执行时间长 等待时间长 查询语句写的烂 查询数据过多 关联了太多的表,太多join 没有利用到索引 单值 复合 服务器调优及各个参数设置(缓冲.线程数等)(不重要DBA的 ...

随机推荐

  1. 【Labview入门】工具的使用

    labview版本:Labview2015 在你使用labview时你可能已经发现,在鼠标移动到连线上时,鼠标会自动的变化,其实这是你选择了自动识别的工具,然后鼠标会根据你所指示的东西自动切换工具类型 ...

  2. TensorFlow2.0(9):TensorBoard可视化

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  3. python- = 与 ==的区别

    一个等号代表的含义是赋值,将某一数值赋给某个变量,比如a=3,将3这个数值赋予给a. 两个等号是判断是否相等,返回True或False,比如1==1.他们是相等的,那么就返回true.1==2,他们是 ...

  4. 说说Object类下面有几种方法呢?

    今天说一道基础题型,不过很多人会忽略或者至少说不完整,但是面试时被问到的几率还是很大的. 面试题 Object有几种方法呢? Java语言是一种单继承结构语言,Java中所有的类都有一个共同的祖先.这 ...

  5. Redis事务深入解析和使用

    作为关系型数据库中一项非常重要的基础功能--事务,在 Redis 中是如何处理并使用的? 1.前言 事务指的是提供一种将多个命令打包,一次性按顺序地执行的机制,并且保证服务器只有在执行完事务中的所有命 ...

  6. PHPStorm 10 配置PHPUnit

    PHPStorm 10 配置PHPUnit PHPUnit的安装 自己用的是Xampp,PHPUnit好像自带不好用. 不说废话: 自己看 According to official site htt ...

  7. OptimalSolution(1)--递归和动态规划(4)其他问题

    一.汉诺塔问题(包括chapter 1中的汉诺塔问题) 二. 三. 四. 五. 六. 七. 八.

  8. Mac OSX 10.7.3 以上系统安装JDK1.7失败 Java from Oracle requires Mac OS X 10.7.3 or later.

    解决办法: 打开JDK dmg安装包,把里面的pkg安装包拖出来然后解包 xar -xf JDK\ 7\ Update\ 40.pkg ./Java 修改Distribution文件找到pm_inst ...

  9. mysql中if函数的正确使用姿势

    --为了今天要写的内容,运行了将近7个小时的程序,在数据库中存储了1千万条数据.-- 今天要说的是mysql数据库的IF()函数的一个实例. 具体场景如下, 先看看表结构: CREATE TABLE ...

  10. Windows 程序包管理器 Chocolatey:一条命令装软件

    Windows 程序包管理器 Chocolatey:一条命令装软件 本文原始地址:https://sitoi.cn/posts/46278.html 介绍 Chocolatey 是一种软件管理解决方案 ...