【问题标题】:Is this the suitable scenario for Multi-column Indexes?这是多列索引的合适场景吗?
【发布时间】:2011-09-25 04:50:11
【问题描述】:

我的编程环境是 Rails 2.3 和 PostgreSQL 8(Heroku 上的共享数据库): 我读过这个 http://devcenter.heroku.com/articles/postgresql-indexes#multicolumn_indexes 以及在我开始以通用方式构建我的应用程序之前互联网上的其他相关资源:

我的表有两列 A 和 B 并且都被索引。 (就(A,B)对而言,这些行是唯一的) 但是在我构建了我的应用程序之后,我发现我只使用两种类型的调用来查询表: myTable.find_by_A_and_B(a,b) 和 myTable.find_by_A(a)

我们预计表中有 10000 多个条目,不同 A 和不同 B 的比率约为 3:1。我们预计,对于 A 中的每个唯一值,B 中将有超过 1000 多行具有不同的值;对于 B 中的每个唯一值,在 A 中具有不同值的行不会超过 300 行。

我的问题是:就 myTable.find_by_A_and_B(a,b) 调用而言,当前的数据库设置(具有两个单独的索引)是否可以归类为“高效”(因为我不知道 PostgreSQL 的内部工作)。以及仅用 (A,B) 的一个多列索引替换这两个索引是否会显着提高速度?

谢谢。

附:作为对评论的回应,这里有更多信息: 根据这个页面,http://devcenter.heroku.com/articles/database 它正在运行 PostgreSQL 8.3

以下是 myTable 的迁移架构:

create_table :myTable do |t|
    t.string :b
    t.integer:a
    t.boolean :c, :default => false
end

add_index :mytable, :b 
add_index :mytable, :a

【问题讨论】:

  • 如果您在 postgres 上提供准确的版本号,我们会更容易。 8.2和8.4有很大区别。此外,像往常一样,表定义会很有帮助。答案取决于ab 的数据类型。最后,了解一下您的实际查询会让您更轻松。
  • 感谢您的澄清 - 作为回报,我编辑了我的答案。

标签: ruby-on-rails postgresql indexing multiple-columns


【解决方案1】:

在 PostgreSQL 的最新版本中,multi-column indexes 可以有效地用于仅过滤其中一列。这在第一列上效果最好,但对其他列也相当不错。

此外,10.000 行对于 PostgreSQL 来说是小菜一碟。具有数百万行的表并不少见。

假设我们在 integer (int4) 列上讨论 btree 索引(默认)...
...答案是:只需在(a,b)上使用一个多列索引。

由于磁盘上的page layout(与表和索引类似),每个索引行都有相当多的开销。此外,由于数据对齐限制,一个索引(a,b) 将使用与仅(a) 上的索引完全相同的磁盘空间量 - 在MAXALIGN = 8 字节的机器上(大多数 64位操作系统)。
因此,特别是如果您有大量写入或有限的磁盘空间和/或 RAM,您最好的选择是仅在 (a,b) 上使用一个多列索引。在大量写入的表上维护索引也需要相当大的成本。

根据问题的更新进行编辑:

  • ainteger,我的回答大部分是有效的。 (a,b) 上的索引将是您需要的全部或大部分内容。

  • 去掉 b 上的单独索引,因为您显然没有对 b 的查询。

  • 由于btext,(a,b) 上的多列索引不能像上面描述的那样从数据对齐中获益,但仍然如此。 b 的中等长度越大,您就越有可能从仅a 的附加索引中获利。使用简短的b 可能不会支付。否则,我希望它能够加快myTable.find_by_A(a) 的速度。

  • 这可能会比ab 上的两个独立索引更快,但幅度不会很大,因为 Postgres 可以在bitmap index scan 中组合两个索引。自 v.8.3 以来,这已得到改进。

  • 请注意,text 上的 btree 索引仅有助于使用 '=' 的查询(如果您在 C 语言环境上运行,则更多)。阅读有关operator classes 的手册。

您不必相信我的话,用EXPLAIN ANALYZE 运行一些测试。它非常简单且内容丰富,为 10.000 行创建索引只需一秒钟左右。重复每个查询几次以填充缓存并获得可比较的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多