AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 117791
Accepted
Dave
Dave
Asked: 2015-10-13 12:38:46 +0800 CST2015-10-13 12:38:46 +0800 CST 2015-10-13 12:38:46 +0800 CST

如何有效缩小某些 Unicode 字段的大小?

  • 772

我们有一个 SQL Server 2012 Enterprise 实时事务数据库,现在每月增长超过 1G,并且正在成为我们的一个大小问题。目前为23G。字符类型字段都是 Unicode,我计算出仅将 2 个这样的字段平均每个 206 个字符转换为非 Unicode 节省了 5G 空间,如果我们将其中的一些从 nchar 和 nvarchar 转换为 char 和varchar 类型。这些字段永远不需要保存不能出现在 SQL_Latin1_General_CP1_CI_AS 排序规则中的 Unicode 字符,因为它们最初以纯 ASCII 形式出现,并且始终按照协议标准这样做。

我是软件架构师和首席 C# 开发人员,尽管只是 DBA 黑客,否则我不会将我们的数据库设计为具有 Unicode 字段用于大量表,而这些表在 3 年前创建数据库时不需要这些字段的 Unicode。在我们最终转换到 AlwaysOn 环境以帮助解决各种性能和备份问题之前,我现在想纠正这个错误。

在缩减这两个或更多字段后,我们希望将数据库缩小一次,以利用节省的空间进行完整备份,并为 AlwaysOn 环境播种。

问题是——

  1. 将列从 nchar/nvarchar 类型缩减为 char/varchar 类型的最安全、最有效的转换技术是什么?特别是 当同一个表中有多个字段需要转换时。我测试了为我想从 nvarchar(max) 转换为 varchar(max) 的两个主要字段执行“添加新列、设置 new=old、删除旧的、将旧的重命名为新的”,这花了 81 分钟我们的测试服务器(4 个虚拟核心,8G 内存)在磁盘空间用完之前即使磁盘上还剩下 8G,并且数据库设置了无限大小(无法为对象'dbo.abc'分配空间。'PK_xyz'在数据库 'xxx' 中,因为 'PRIMARY' 文件组已满)。在收到磁盘警告后,我确实在完成之前删除了一个旧数据库,所以它可能没有计算那个新空间。不管它太慢了。这只是这些列中最大的两个(1260 万行),并且只占用 2% 到 3% 的 CPU 忙,因此看起来效率不高,并且如果我们要转换这两个字段甚至更不用说任何其他字段,则表示不可接受的停机时间。这两个字段的平均字段大小仅为 206 个字符或 412 个字节。我打算尝试的另一种技术是在新模式中创建新表 def,从旧表中选择它,然后在模式之间移动表并删除旧表。我在桌面上有一个 FK 和索引要处理。我打算尝试的另一种技术是在新模式中创建新表 def,从旧表中选择它,然后在模式之间移动表并删除旧表。我在桌面上有一个 FK 和索引要处理。我打算尝试的另一种技术是在新模式中创建新表 def,从旧表中选择它,然后在模式之间移动表并删除旧表。我在桌面上有一个 FK 和索引要处理。

  2. 如果我弄清楚如何在可接受的维护窗口内有效地执行#1,那么进行一次性收缩并最终得到有组织/重建的索引和更新的统计信息的最安全做法是什么?我理解不进行常规收缩的逻辑,有时它实际上可以增加尺寸。

  3. 是否有任何第三方工具可以进行备份并将其恢复到具有修改后的字段定义或以其他方式转换某些字段类型的新数据库中?

欢迎提出任何建议和最佳实践。

谢谢,戴夫

sql-server-2012 unicode
  • 2 2 个回答
  • 311 Views

2 个回答

  • Voted
  1. Best Answer
    Solomon Rutzky
    2015-10-13T12:53:55+08:002015-10-13T12:53:55+08:00

    关于:

    我测试了为我想从 nvarchar(max) 转换为 varchar(max) 的两个主要字段执行“添加新列、设置 new=old、删除旧的、将旧的重命名为新的”,这花了 81 分钟我们的测试服务器……在磁盘空间用完之前……太慢了。

    和

    我打算尝试的另一种技术是在新模式中创建新表 def,从旧表中选择它,然后在模式之间移动表并删除旧表。

    一般来说,使用理想模式制作表的副本是我的首选方法。但是,如果您现在可能只有足够的空间来转换两列,您确定您有足够的空间来制作整个表格的副本吗?

    此外,新表只需要有一个不同的名称。它不需要在不同的模式中。

    由于您使用的是企业版,您是否考虑过甚至考虑过启用数据压缩?它不仅会产生您在NCHAR/NVARCHAR字段上寻找的效果,而且还会在其他类型的其他字段上节省空间。

    有两种类型的压缩:行和页。您应该仔细阅读它们并运行存储过程来估计您的节省金额。

    启用压缩可以作为一项ONLINE操作来完成,但可能需要一些磁盘空间。如果您没有可用空间,那么您可以考虑一种混合方法,您可以将表的副本构建为TableNEW,并且已经创建了聚簇索引,并在启用压缩的情况下创建。然后你应该可以慢慢填充TableNEW,数据会在输入时压缩。当然,你会想使用 INSERT INTO...SELECT 来批量完成。直到您删除原始表并对TableNEW.

    • 数据压缩的主要 MSDN 文档。
    • 对表或索引启用压缩
    • sp_estimate_data_compression_savings(在上面直接列出的“启用压缩”文档中提到)

    请记住,在某些情况下,您可能不会节省那么多空间,或者节省空间不值得增加 CPU 活动。但是,这一切都取决于很多因素,所以它确实应该在您的系统上进行测试。

    你总是可以采取以下方法:

    1. 启用压缩,直接对当前表作为 ONLINE(如果有足够的空间来支持它),或者对一个单独的表启用压缩。
    2. 如果您发现 CPU 的增加实际上超出了空间节省带来的好处,那么您可以选择使用常规 VARCHAR 字段再次构建表并且不进行压缩。因为已经启用了压缩,所以您现在绝对应该有足够的空间来进行压缩。

    但同样,就像我们所做的任何事情一样,它应该经过测试。多年来,我一直听说 CPU 上的“XML 解析”有多糟糕,压缩应该有多糟糕,但实际上,这些担忧常常被夸大了。唯一知道的方法是在您的系统上进行测试。(ps,以防万一不清楚是纯文本媒体,这些最后的陈述并不是在攻击@Kin 在他的回答中所说的需要对 CPU 活动增加保持谨慎。他是正确的,至少在某种程度上是正确的。我只是提醒大家一定要从当前的硬件和软件以及系统设置的角度来考虑。)

    • 5
  2. Kin Shah
    2015-10-13T13:20:28+08:002015-10-13T13:20:28+08:00
    1. 将列从 nchar/nvarchar 类型缩减为 char/varchar 类型的最安全、最有效的转换技术是什么?

    您可以使用架构开关或添加可为空的 varchar(具有适当长度)列和批处理(例如 1K 或 10K)更新行,更新完成后,删除旧列并重命名新列。最后,重建索引。

    另一种方法是创建一个具有所需正确数据类型的单独数据库,bcp 输出数据并将数据批量插入新数据库,然后重建索引并将其重命名为旧名称(删除旧数据库)。

    本机格式的 BCP 和批量插入非常快,因为您将在同一台服务器上进行。此过程假定您有足够的磁盘空间。 我在不到 20 分钟的时间内完成了一个 400GB 的数据库 bcp out 和批量插入。像往常一样,彻底测试您的整个过程,并且您必须在维护窗口期间执行此操作。

    1. 进行一次性收缩并最终得到有组织/重建的索引和更新的统计信息的最安全做法是什么?

    如果您确定您的数据库永远不会再增长到那个大小,那么缩小它就会给您那个空间。确保你有一个合理的自动增长设置(并保持自动增长以 MB 为单位而不是以百分比为单位)并预先调整你的数据和日志文件(这样它们就不必经常自动增长)。还启用即时文件初始化,以便数据文件可以利用它的强大功能。

    1. 是否有任何第三方工具可以进行备份并将其恢复到具有修改后的字段定义或以其他方式转换某些字段类型的新数据库中?

    从来没听说过。我会说这是不可能的,除非你暗示 - 与你当前的数据库和未来的数据库(具有正确数据类型的数据库)进行模式比较并生成脚本进行同步。为此,Redgate 的模式比较是一个极好的工具。我用过它,它是救命稻草!

    我同意上面关于使用数据压缩的答案- 行或页,但它伴随着CPU 的费用。

    • 2

相关问题

  • SQL Server 2012 在 TempDb 中使用排序创建索引 - 获得 False?

  • SQL Server AlwaysOn 故障转移透明度

  • 为什么 Denali 序列应该比标识列表现更好?

  • SQL Server 不应该支持范围吗?

  • 什么是 SQL Server“德纳利”?什么是新的?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve