SQL Server 到 PostgreSQL - 迁移和设计问题

问题描述 投票:0回答:2

目前正在从 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 台)服务器将数据(逗号分隔的文本文件)转储到导入服务器上。

导入:

  • 文章表上的索引已禁用。
  • 对于每个转储的文本文件
    • 数据被批量复制到临时表。
    • 临时表已更新。
    • 服务器的旧数据已从文章表中删除。
    • 临时表数据复制到 Articles 表。
    • 临时表已删除。

所有服务器完成此过程后,将构建索引并将新数据库复制到 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 服务器(有索引)可以呈现报告。也许将系统减少到一台服务器可以跳过网络阶段的复制。这一台服务器将有两个版本的数据库:一个具有用于交付报告的索引,另一个不用于导入新数据。数据库每天都会交换。想法?

这是一个很棒的系统,不管你相信与否,有一些方法可以通过对其进行大的调整来让我变得疯狂。

更新:我不是在寻求关系数据库方面的帮助,而是希望与数据仓库专家交流想法。

sql-server database-design postgresql
2个回答
1
投票

我不是数据仓库专家,但有几点建议。

看起来您的数据可以轻松分区。请参阅 Postgresql 有关分区的文档,了解如何将数据拆分到不同的物理表中。这使您可以按照自然的每服务器粒度管理数据。

您可以使用 postgresql 事务性 DDL 来避免一些复制。对于每个输入文件,该过程将如下所示:

  1. 创建一个新表来存储数据。
  2. 使用 COPY 将数据批量加载到表中。
  3. 创建任何必要的索引并进行任何所需的处理。
  4. 在事务中删除旧分区,重命名新表并将其添加为分区。

如果您这样做,您可以根据需要随时更换分区。只有最后一步需要锁定活动表,这是一个快速的 DDL 元数据更新。

避免删除数据并将其重新加载到索引表中 - 由于 PostgreSQL 使用的 MVCC 机制,这将导致表和索引相当大的膨胀。如果您只是交换基础表,您将获得一个漂亮的紧凑表和索引。如果您的查询中的分区之上有任何数据局部性,则可以在该局部性上对输入数据进行排序,或者如果不可能,则使用 PostgreSQL 集群功能 对数据进行物理重新排序。

为了加快文本搜索速度,如果约束可以接受(只能在单词边界搜索),请使用 GIN 全文索引。或者如果您需要搜索任意子字符串,则可以使用三元组索引(由 pg_trgm 扩展模块提供)。


0
投票

修复慢查询: 从文章中选择*,其中article_title LIKE '%criteria%'

创建一个表(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 都会切换。 希望您能读完这一切。在我看来这是有道理的。 实施有时会产生其他问题,因为在这种规模上没有什么是容易的。

© www.soinside.com 2019 - 2024. All rights reserved.