热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PostgreSQL中的索引介绍(三)

访问方法(即索引类型)必须提供自身的相关信息,本篇文章将介绍

翻译:尚凯

审核:魏波

Egor Rogov
俄罗斯Postgres Professional公司数据库专家

     上期介绍与索引相关的内容,主要包括空值与索引、索引类型示例、索引与排序、并行创建。(关注文末二维码,往期文章不迷路)。
     在接下来的内容中将介绍访问方法接口的结构。

目录

1 属性

2 运算符类和族

3 系统目录


属性

      访问方法的所有属性都存储在«pg_am»表中(“am”代表访问方法)。我们还可以从同一个表中获取可用方法的列表:

    postgres=# select amname from pg_am;
    amname
    --------
    btree
    hash
    gist
    gin
    spgist
    brin
    (6 rows)

          虽然顺序扫描可以正确地引用访问方法,但由于历史原因,它不在此列表中。

         在PostgreSQL9.5及更低版本中,每个属性都用«pg_am»表的单独字段表示。从9.6版本开始,属性使用特殊函数进行查询,并被分为多个层:

    (1)访问方法属性 - «pg_indexam_has_property»

    (2)特定索引的属性 - «pg_index_has_property»

    (3)索引各列的属性 - «pg_index_column_has_property»

          展望未来,访问方法层和索引层是分开的:到目前为止,所有基于一种访问方法的索引始终具有相同的属性。


     1.以下是访问方法的4个属性(通过«btree»的示例)

      postgres=# select a.amname, p.name, pg_indexam_has_property(a.oid,p.name)from pg_am a,
      unnest(array['can_order','can_unique','can_multi_col','can_exclude']) p(name)where a.amname = 'btree'order by a.amname;
      amname | name | pg_indexam_has_property
      --------+---------------+-------------------------
      btree | can_order | t
      btree | can_unique | t
      btree | can_multi_col | t
      btree | can_exclude | t
      (4 rows)

      (1) can_order

      访问方法使我们能够在创建索引时指定值的排序顺序(目前仅适用于«btree»)。

      (2)  can_unique

      支持唯一约束和主键(仅适用于«btree»)。

      (3) can_multi_col
      可以在多个列上构建索引。

      (4) can_exclude
      支持排除约束EXCLUDE。


       2.以下属性与索引有关(让我们以一个现有的索引为例)

        postgres=# select p.name, pg_index_has_property('t_a_idx'::regclass,p.name)from unnest(array[
        'clusterable','index_scan','bitmap_scan','backward_scan'
        ]) p(name);
        name | pg_index_has_property
        ---------------+-----------------------
        clusterable | t
        index_scan | t
        bitmap_scan | t
        backward_scan | t
        (4 rows)

        (1) clusterable

        以根据索引重新排序行(使用同名命令CLUSTER进行)。

        (2) index_scan

        支持索引扫描。尽管此属性可能看起来很奇怪,但并非所有索引都可以逐个返回TID-有些索引一次返回所有结果,并且只支持位图扫描。

        (3) bitmap_scan 

        支持位图扫描。

        (4) backward_scan

        可以按照构建索引时指定的顺序返回结果。


         3.以下是列属性

          postgres=# select p.name,
          pg_index_column_has_property('t_a_idx'::regclass,1,p.name)from unnest(array[
          'asc','desc','nulls_first','nulls_last','orderable','distance_orderable',
          'returnable','search_array','search_nulls'
          ]) p(name);
          name | pg_index_column_has_property
          --------------------+------------------------------
          asc | t
          desc | f
          nulls_first | f
          nulls_last | t
          orderable | t
          distance_orderable | f
          returnable | t
          search_array | t
          search_nulls | t
          (9 rows)

          (1) asc,desc,nulls_first,nulls_last,orderable

          这些属性与值的排序有关(我们将在讨论«btree»索引时进一步描述)。

          (2) distance_orderable

          结果可以按操作确定的排序顺序返回(目前仅适用于GiST和RUM索引)。

          (3) returnable

          可以在不访问表的情况下使用索引,即支持仅索引扫描。

          (4) search_array

          支持使用表达式:

          « indexed-field IN(list_of_constants)» 搜索多个值,

          该表达式

          与« indexed-field=ANY(array_of_constants)»相同。

          (5)search_nulls

          可以通过IS NULL和IS NOT NULL条件进行搜索。


                我们已经详细讨论了一些属性。有些属性是特定于某些访问方法的。我们将在考虑这些具体方法时进一步展开描述。


          运算符类和族

                 除了由所描述的接口公开的访问方法的属性之外,还需要信息来了解访问方法接受哪些数据类型和哪些操作符。为此,PostgreSQL引入了运算符类和运算符族概念。

                 运算符类包含用于操作特定数据类型的索引的最小运算符集(可能还有辅助函数)。

                 运算符类包含在某些运算符族中。此外,如果一个公共运算符族具有相同的语义,则它们可以包含多个运算符类。

                 例如,«integer_ops»系列:

                 包括«int8_ops»,«int4_ops»和«int2_ops»类,

                 用于类型«bigint»,«integer»和«smallint»,它们的大小不同,但含义相同:

            postgres=# select opfname, opcname, opcintype::regtypefrom pg_opclass opc, pg_opfamily opfwhere opf.opfname = 'integer_ops'and opc.opcfamily = opf.oidand opf.opfmethod = (
            select oid from pg_am where amname = 'btree'
            );
            opfname | opcname | opcintype
            -------------+----------+-----------
            integer_ops | int2_ops | smallint
            integer_ops | int4_ops | integer
            integer_ops | int8_ops | bigint
            (3 rows)

                   另一个例子:«datetime_ops»系列包括操作日期的运算符类(有时间和无时间):

              postgres=# select opfname, opcname, opcintype::regtypefrom pg_opclass opc, pg_opfamily opfwhere opf.opfname = 'datetime_ops'and opc.opcfamily = opf.oidand opf.opfmethod = (
              select oid from pg_am where amname = 'btree'
              );
              opfname | opcname | opcintype
              --------------+-----------------+-----------------------------
              datetime_ops | date_ops | date
              datetime_ops | timestamptz_ops | timestamp with time zone
              datetime_ops | timestamp_ops | timestamp without time zone
              (3 rows)

                      运算符族还可以包括其他运算符来比较不同类型的值。将谓词分组为多个族,使计划器能够为具有不同类型值的谓词使用索引。一个族也可以包含其他辅助功能。

                      在大多数情况下,我们不需要了解有关运算符族和类的任何信息。通常我们只是创建一个索引,默认情况下使用某个运算符类。

                      但是,我们可以显式指定运算符类。这是一个简单的示例,说明何时需要显式规范:在排序规则与C不同的数据库中,常规索引不支持LIKE操作:

                postgres=# show lc_collate;
                lc_collate
                -------------
                en_US.UTF-8
                (1 row)
                postgres=# explain (costs off) select * from t where b like 'A%';
                QUERY PLAN
                -----------------------------
                Seq Scan on t
                Filter: (b ~~ 'A%'::text)
                (2 rows)

                        我们可以通过使用运算符类«text_pattern_ops»创建索引来克服此限制(注意计划中的条件如何更改):

                  postgres=# create index on t(b text_pattern_ops);
                  postgres=# explain (costs off) select * from t where b like 'A%';
                  QUERY PLAN
                  ----------------------------------------------------------------
                  Bitmap Heap Scan on t
                  Filter: (b ~~ 'A%'::text)
                  -> Bitmap Index Scan on t_b_idx1
                  Index Cond: ((b ~>=~ 'A'::text) AND (b ~<~ 'B'::text))
                  (4 rows)


                  系统目录

                            在本文的结尾,我们提供了系统目录中与运算符类和族直接相关的表的简化图。

                         不用多说,所有这些表都有详细的描述。

                         系统目录使我们无需查找文档即可找到许多问题的答案。例如,某种访问方法可以操纵哪些数据类型?

                    postgres=# select opcname, opcintype::regtypefrom pg_opclasswhere opcmethod = (select oid from pg_am where amname = 'btree')order by opcintype::regtype::text;
                    opcname | opcintype
                    ---------------------+-----------------------------
                    abstime_ops | abstime
                    array_ops | anyarray
                    enum_ops | anyenum
                    ...

                            运算符类包含哪些运算符(因此,索引访问可用于包含此类运算符的条件)?

                      postgres=# select amop.amopopr::regoperatorfrom pg_opclass opc, pg_opfamily opf, pg_am am, pg_amop amopwhere opc.opcname = 'array_ops'and opf.oid = opc.opcfamilyand am.oid = opf.opfmethodand amop.amopfamily = opc.opcfamilyand am.amname = 'btree'and amop.amoplefttype = opc.opcintype;
                      amopopr
                      -----------------------
                      <(anyarray,anyarray)
                      <=(anyarray,anyarray)
                      =(anyarray,anyarray)
                      >=(anyarray,anyarray)
                      >(anyarray,anyarray)
                      (5 rows)


                      下期预告

                      下篇文章将关于“特种类型的索引介绍之哈希索引


                      欢迎投稿



                              中国开源软件推进联盟PostgreSQL分会,欢迎大家积极投稿,向PGer分享自己的实践经验、心得体会,共建PG中国生态。

                      投稿邮箱:

                      press@postgresqlchina.com

                      原文请点击下方“阅读原文”获取



                      推荐阅读
                      • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
                      • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
                      • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
                      • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
                      • 知识图谱——机器大脑中的知识库
                        本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
                      • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
                      • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
                        原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
                      • Ubuntu安装常用软件详细步骤
                        目录1.GoogleChrome浏览器2.搜狗拼音输入法3.Pycharm4.Clion5.其他软件1.GoogleChrome浏览器通过直接下载安装GoogleChro ... [详细]
                      • 向QTextEdit拖放文件的方法及实现步骤
                        本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
                      • Python正则表达式学习记录及常用方法
                        本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
                      • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
                      • 索引库类似于查字典的检索表或图书馆的书目检索,是搜索引擎将抓取的网页放入的地方。索引库通过词语来分类,利用固定数量的词语进行分类,方便搜索引擎匹配用户查询的词语。本文介绍了索引库的分类方式及其好处。 ... [详细]
                      • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
                      • 数字账号安全与数据资产问题的研究及解决方案
                        本文研究了数字账号安全与数据资产问题,并提出了解决方案。近期,大量QQ账号被盗事件引起了广泛关注。欺诈者对数字账号的价值认识超过了账号主人,因此他们不断攻击和盗用账号。然而,平台和账号主人对账号安全问题的态度不正确,只有用户自身意识到问题的严重性并采取行动,才能推动平台优先解决这些问题。本文旨在提醒用户关注账号安全,并呼吁平台承担起更多的责任。令牌云团队对此进行了长期深入的研究,并提出了相应的解决方案。 ... [详细]
                      • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
                      author-avatar
                      LIN-少爷
                      这个家伙很懒,什么也没留下!
                      PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
                      Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有