我发现创建一个触发器只是为了获取表的当前总行而不执行COUNT(*)FROM表,这很麻烦。我在想他们为Postgres 8.5计划的索引组织表是否可以实现?
答案 0 :(得分:3)
我不认为索引组织表必须更快地扫描以计算所有可见元组。从逻辑上讲,它必须经历相同数量的数据,无论它是否有条理,以便数据在b树叶子节点或现有的堆格式中。
目前,postgresql索引仅存储[key,ctid]对(基本上)。 (ctid本质上是一个“rowid” - 堆页面编号和元组行指针索引)所以你不能只通过索引计算表中的行,因为你需要检查每个元组的[xmin,xmax] - 而且只保留堆中的数据。
你也可以将[xmin,xmax]放在索引中 - 不时提出这个建议。但这会使指数膨胀,并且有用的是所有更新/删除都必须确保它们保持最新:这会导致问题,尤其是因为执行更新所涉及的工作现在已经扩大了一些数量按表上的索引数量。对于像tsvector这样的重型索引,或基于昂贵的用户表达式的索引,这可能需要一段时间,并且在一些令人讨厌的情况下根本不起作用,行现在似乎在索引中存在,但是在堆。此练习的重点应该是允许数据库尽可能依赖索引中的实时信息。即使您正在更新非索引列,也会产生此成本 - 团队需要努力加速8.3(仅限堆的元组)。
我认为一种可能性是将索引标记为可选地具有[xmin,xmax] - 例如只标记pkey索引。然后必须有计划员的变化,以确定何时这是一个优势 - 这似乎是相当多的工作。
索引组织表,如果它们像我认为的那样工作在Oracle(和SQL Server,其中任何具有聚簇索引的表基本上是索引组织的)通过将[key,tuple]存储在主键索引中来工作(并且可能是[key,pkey]在所有其他人中) - 没有ctid,没有堆。所以“元组”将包含[xmin,xmax,cminmax,natts,....]等,你可以通过扫描索引来满足“从表中选择计数(*)”。但这基本上和扫描堆上的元组一样 - 它们不会神奇地占用更少的空间,因为它们现在处于“索引”中。
AFAICT索引组织表的主要原因是具有单个主键索引的小表将占用1页而不是3页,并且主键索引扫描可能会快一些。我似乎记得我给IOT提出的Oracle相关建议是它们用于静态维度表,而不是通用用途,部分原因是维护二级索引的成本(我不认为Oracle存储[在IOT二级索引中的key,pkey],而是某种替代rowid)。
答案 1 :(得分:0)