PostgreSQL SQL 语言:索引

    xiaoxiao2022-05-22  256

    本文档为PostgreSQL 9.6.0文档,本转载已得到原译者彭煜玮授权。

    1. 简介

    假设我们有一个如下的表:

    CREATE TABLE test1 ( id integer, content varchar );

    而应用发出很多以下形式的查询:

    SELECT content FROM test1 WHERE id = constant;

    在没有事前准备的情况下,系统不得不扫描整个test1表,一行一行地去找到所有匹配的项。如果test1中有很多行但是只有一小部分行(可能是0或者1)需要被该查询返回,这显然是一种低效的方式。但是如果系统被指示维护一个在id列上的索引,它就能使用一种更有效的方式来定位匹配行。例如,它可能仅仅需要遍历一棵搜索树的几层而已。

    类似的方法也被用于大部分非小说书籍中:经常被读者查找的术语和概念被收集在一个字母序索引中放在书籍的末尾。感兴趣的读者可以相对快地扫描索引并跳到合适的页而不需要阅读整本书来寻找感兴趣的材料。正如作者的任务是准备好读者可能会查找的术语一样,数据库程序员也需要预见哪些索引会有用。

    正如前面讨论的,下列命令可以用来在id列上创建一个索引:

    CREATE INDEX test1_id_index ON test1 (id);

    索引的名字test1_id_index可以自由选择,但我们最好选择一个能让我们想起该索引用途的名字。

    为了移除一个索引,可以使用DROP INDEX命令。索引可以随时被创建或删除。

    一旦一个索引被创建,就不再需要进一步的干预:系统会在表更新时更新索引,而且会在它觉得使用索引比顺序扫描表效率更高时使用索引。但我们可能需要定期地运行ANALYZE命令来更新统计信息以便查询规划器能做出正确的决定。通过Chapter 14的信息可以了解如何找出一个索引是否被使用以及规划器在何时以及为什么会选择不使用索引。

    索引也会使带有搜索条件的UPDATE和DELETE命令受益。此外索引还可以在连接搜索中使用。因此,一个定义在连接条件列上的索引可以显著地提高连接查询的速度。

    在一个大表上创建一个索引会耗费很长的时间。默认情况下,PostgreSQL允许在索引创建时并行地进行读(SELECT命令),但写(INSERT、UPDATE和DELETE)则会被阻塞直到索引创建完成。在生产环境中这通常是不可接受的。在创建索引时允许并行的写是可能的,但是有些警告需要注意,更多信息可以参考并发构建索引。

    一个索引被创建后,系统必须保持它与表同步。这增加了数据操作的负担。因此哪些很少或从不在查询中使用的索引应该被移除。

    2. 索引类型

    PostgreSQL提供了多种索引类型: B-tree、Hash、GiST、SP-GiST 、GIN 和 BRIN。每一种索引类型使用了 一种不同的算法来适应不同类型的查询。默认情况下, CREATE INDEX命令创建适合于大部分情况的B-tree 索引。

    B-tree可以在可排序数据上的处理等值和范围查询。特别地,PostgreSQL的查询规划器会在任何一种涉及到以下操作符的已索引列上考虑使用B-tree索引:

    < <= = >= >

    将这些操作符组合起来,例如BETWEEN和IN,也可以用B-tree索引搜索实现。同样,在索引列上的IS NULL或IS NOT NULL条件也可以在B-tree索引中使用。优化器也会将B-tree索引用于涉及到模式匹配操作符LIKE和~ 的查询,前提是如果模式是一个常量且被固定在字符串的开头—例如:col LIKE 'foo%'或者col ~ '^foo', 但在col LIKE '

    转载请注明原文地址: https://yun.8miu.com/read-11474.html

    最新回复(0)