【问题标题】:Should I use hash or btree for a foreign key index in postgresql 9.3?我应该在 postgresql 9.3 中使用散列或 btree 作为外键索引吗?
【发布时间】:2014-12-05 11:45:39
【问题描述】:

在 postgresql 9.3 中哪个索引对整数类型的外键表现更好?

我会假设一个哈希索引,因为外键比较总是用 = 进行的

或者当用于外键的 JOINS 时,btree 的比较速度是否与散列一样快?

因为在 postgresql 中主键使用 btree,这表明它们也更适合外键。

【问题讨论】:

    标签: hash foreign-keys postgresql-9.3


    【解决方案1】:

    来自manual On PostgreSQL 9.3

    注意哈希索引操作目前没有 WAL 记录,所以哈希 数据库崩溃后可能需要使用REINDEX 重建索引 如果有不成文的更改。此外,哈希索引的更改不会 在初始之后通过流式复制或基于文件的复制进行复制 基本备份,因此他们对随后的查询给出错误的答案 使用它们。由于这些原因,目前不鼓励使用哈希索引。

    也没有证据表明哈希索引比 btree 具有任何性能优势。

    【讨论】:

    • 很奇怪。您可能会认为哈希索引会快得多,但许多基准测试表明它充其量只是稍微快一点。对于典型的内存数据结构(例如 Java 的 HashMapTreeMap),哈希比基于树的要快得多。 Postgres 速度慢的原因是什么,或者仅仅是因为 Postgres 的哈希索引实现没有得到很好的维护?
    • 这在 postgresql 10+ 中不再相关 postgresql.org/docs/10/sql-createindex.html
    • @sudo 大树具有更好的数据局部性,而哈希表是随机分布的。缓存性能有很大的不同,尤其是从磁盘读取时。
    • IIRC 即使在 Postgres 10+ 中将我的索引切换为哈希也没有显示出任何改进。我忘记了当时的情况。数据局部性...我不明白为什么在平等检查期间这会有所帮助,除非对一侧进行排序。
    【解决方案2】:

    您能解释一下外键是如何在内部创建的吗? 当我在创建约束时运行 iostat 时,没有写入磁盘但有很多读取。对于单线程 PostgreSQL 系统,创建外键的过程是非常 I/O(读取)和 CPU 密集型的。

    【讨论】:

      【解决方案3】:

      视情况而定。

      如果您不使用外键进行任何查询,则使用you don't need any index。参照完整性是使用被引用主键的索引来强制执行的。

      因此,对于任何列,使用哪种索引类型(如果有)的问题都是相同的。如果您的查询将受益于= 比较的索引,并且您使用的是 PostgreSQL 10 或更新版本,那么 HASH 索引是一个合理的选择。如果同一列涉及任何排序操作(ORDER BY<>= 等),那么您也可以使用 BTREE。

      如果您高度关注相对性能,那么您需要自己测试它们,使用您自己的数据分布和查询负载。由于数据访问的局部性(顺序与随机),树索引的性能仍可能优于哈希。

      【讨论】:

        猜你喜欢
        • 2011-12-22
        • 1970-01-01
        • 2013-03-20
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多