目前正在从 SQL Server 迁移到 PostgreSQL,并尝试改进其中的几个关键领域:
我有一个文章表:
CREATE TABLE [dbo].[Articles](
[server_ref] [int] NOT NULL,
[article_ref] [int] NOT NULL,
[article_title] [varchar](400) NOT NULL,
[category_ref] [int] NOT NULL,
[size] [bigint] NOT NULL
)
每天约有 500 台(约 1000 台)服务器将数据(逗号分隔的文本文件)转储到导入服务器上。
导入:
所有服务器完成此过程后,将构建索引并将新数据库复制到 Web 服务器。
我对这个过程相当满意,但当我努力实现实时(哈哈!)系统时,总是有改进的空间。我正在做的事情正确吗? Articles 表包含约 5 亿条记录,并且预计还会增长。在这个表中搜索是可以的,但还可以更好。即
SELECT * FROM Articles WHERE server_ref=33 AND article_title LIKE '%criteria%'
已经令人满意,但我想提高搜索速度。显然“喜欢”是我的问题。建议? SELECT * FROM Articles WHERE article_title LIKE '%criteria%'
太可怕了。
分区是 SQL Server Enterprise 的一项功能,但它也是 PostgreSQL 众多令人兴奋的前景之一。导入过程(删除数据、插入数据)和构建索引会对性能造成什么影响?数据库会大幅增长吗?
数据库目前为 200 GB,并将继续增长。通过网络复制它并不理想,但它可以工作。我正在考虑改变系统的硬件结构。拥有导入服务器和 Web 服务器的想法是,导入服务器可以完成脏活(没有索引),而 Web 服务器(有索引)可以呈现报告。也许将系统减少到一台服务器可以跳过网络阶段的复制。这一台服务器将有两个版本的数据库:一个具有用于交付报告的索引,另一个不用于导入新数据。数据库每天都会交换。想法?
这是一个很棒的系统,不管你相信与否,有一些方法可以通过对其进行大的调整来让我变得疯狂。
更新:我不是在寻求关系数据库方面的帮助,而是希望与数据仓库专家交流想法。
我不是数据仓库专家,但有几点建议。
看起来您的数据可以轻松分区。请参阅 Postgresql 有关分区的文档,了解如何将数据拆分到不同的物理表中。这使您可以按照自然的每服务器粒度管理数据。
您可以使用 postgresql 事务性 DDL 来避免一些复制。对于每个输入文件,该过程将如下所示:
如果您这样做,您可以根据需要随时更换分区。只有最后一步需要锁定活动表,这是一个快速的 DDL 元数据更新。
避免删除数据并将其重新加载到索引表中 - 由于 PostgreSQL 使用的 MVCC 机制,这将导致表和索引相当大的膨胀。如果您只是交换基础表,您将获得一个漂亮的紧凑表和索引。如果您的查询中的分区之上有任何数据局部性,则可以在该局部性上对输入数据进行排序,或者如果不可能,则使用 PostgreSQL 集群功能 对数据进行物理重新排序。
为了加快文本搜索速度,如果约束可以接受(只能在单词边界搜索),请使用 GIN 全文索引。或者如果您需要搜索任意子字符串,则可以使用三元组索引(由 pg_trgm 扩展模块提供)。
创建一个表(dbo.tblTitle_Words),其中标题的每个单词作为表中的唯一条目。 然后运行交叉联接来创建一个查找表 (dbo.tblArticle_Title_Lookup),该表将创建一个表(或插入缺失值) dbo.tblArticle_Title_Lookup(下面的字段) ArticleID(来自article_title表的(某些主键类型)) , TitleWord nvarchar(255), 索引该表, 然后运行 SELECT @ID=ArticleID FROM dbo.tblArticle_Title_Lookup WHEREarticle_title LIKE '%criteria%' 获取@ID 和 从文章标题中选择 *,其中 PrimaryKey = @ID 如果你重建你的,应该会更快 每次加载数据时,Alpha/Bravo 中的 dbo.tblTitle_Words 和 dbo.tblArticle_Title_Lookup 都会切换。 希望您能读完这一切。在我看来这是有道理的。 实施有时会产生其他问题,因为在这种规模上没有什么是容易的。