2

我有一个用户表和一个文档表。文档只有一个用户作为所有者,对于我正在构建的应用程序,我知道我通常会访问与单个给定用户关联的一组文档。

假设普通用户有 K 个文档,并且某些常见查询获取给定用户的所有文档。我不希望我的数据库(PostgreSQL)必须进行 K 磁盘搜索(平均而言)来获取用户的所有文档。理想情况下,文档将存储在连续的块中,以便获取只需要几次搜索。

组织文档表模式以创建这样的位置是否可能(并且合理)?我知道无 SQL 实现总是这样做吗?例如,BigTable 论文讨论了如何通过 URL 分配 web 表的行键,除了 url 是颠倒的,例如 com.cnn.www,以便 CNN 的所有页面在数据存储中彼此靠近。在 Postgres 中似乎不可能有类似的东西,因为这些表不能按索引组织,尽管在带有 InnoDB 的 MySQL 中可能是可能的。 这篇文章得出了类似的结论。

4

1 回答 1

1

您正在寻找的命令是CLUSTER,但它有缺点。当您运行它时,它会完全重写表,这需要对其进行锁定,因此您可能只想在流量较低时执行此操作。此外,Postgres 不会在 INSERT 和 UPDATE 期间保持行的顺序,因此您的数据会随着表的写入而分散,您可能必须定期重新聚集它。

您还可以在表上设置较低的填充因子,以便更新更有可能将给定行保留在同一页面上。这应该可以防止一些碎片,这些碎片只会留下 INSERT,但填充因子较低的 INSERT 往往会放置在较新的页面上,并且这些页面可能会被普遍访问以保存在 RAM 中。我在假设您的使用模式可能是错误的,但无论如何,您最好的做法可能是在您看到 I/O 开始成为问题时重新集群。

最后,还有一个名为pg_repack的工具,它可以在不占用如此重锁的情况下对表进行集群,其方式类似于 CREATE INDEX CONCURRENTLY 的工作方式,但它是第三方工具,因此您需要在运行之前对其进行试验在生产中。

于 2013-10-31T00:05:17.147 回答