使用 SQLCMD 执行 MS SQL Server (*.sql) 脚本备份还原操作有啥问题?

Posted

技术标签:

【中文标题】使用 SQLCMD 执行 MS SQL Server (*.sql) 脚本备份还原操作有啥问题?【英文标题】:What is wrong with MS SQL Server (*.sql) script backup restore operation with SQLCMD?使用 SQLCMD 执行 MS SQL Server (*.sql) 脚本备份还原操作有什么问题? 【发布时间】:2021-12-22 18:50:48 【问题描述】:

我有一个 6GB *.sql 脚本备份文件,当我加载到数据库时:

sqlcmd -S .\SQLEXPRESS -U SA -d testdbb -i whole_DB_backup.sql -o result.log

完成脚本需要几天时间。相反,对于同一数据库*.bak 备份文件,从SQL Server Management Studio 内部加载到数据库服务器只需5 分钟。 幕后有什么问题吗?如何加快sqlcmd 恢复操作?

【问题讨论】:

如果您在这里没有得到好的答案,您可以在dba.stackexchange.com 上尝试这个问题。至于为什么,基本上归结为恢复 .bak 文件只是简单地替换数据库中的数据,而 sqlcmd 将进行几百万次插入,这需要更新索引、检查约束等,这需要花费大量时间。 不知道您的脚本是如何编写的,我们无法提供太多帮助。大概您的脚本包含您需要的所有CREATEALTERINSERT 等语句。例如,您可能只在每个 INSERT 语句中插入 1 行;一种非常缓慢的插入方式。 恢复备份文件总是比运行一个巨大的脚本更快,该脚本包含创建架构的语句和一次插入所有数据的语句。当您需要“备份”到较低版本或版本的数据库引擎(如果这是您的脚本方法的原因)时,这就是预期的结果。 @SMor:普通的 SQL 脚本让我可以探索终端 vim 上的内容。相反,*.BAK 文件让我只能在 ssme 中探索。不幸的是,对于这个特定的数据库快照,我只有 *.SQL 备份。 【参考方案1】:

原因是您不是在加载 6G 备份,而是在运行 6G SQL 脚本。每一个INSERT,每一个CREATE TABLEUPDATESELECT等都必须由SQL Server解析,为每条语句生成一个查询计划,几乎可以肯定,大多数SQL语句都是不会被缓存——这不会涉及事务开销和运行 SQL 时需要完成的其他事情。

另一方面,执行RESTORE 在大多数情况下不必处理任何这些,除了从 .bak 创建完整数据库所需的开销。

基本上,这个过程会很慢,解决这个问题的唯一方法是编写一个脚本来解析 .SQL 文件并将其转换为您可以在 BCP 中使用的东西或其他东西。只需运行脚本并咬紧牙关。

【讨论】:

以上是关于使用 SQLCMD 执行 MS SQL Server (*.sql) 脚本备份还原操作有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

求大神解决sqlcmd执行sql文件忽略错误的问题

从WiX使用SQLCMD执行二进制SQL文件

如何使用sqlcmd在批处理脚本中执行SQL?

MS SQL2008执行大脚本文件时,提示“内存不足”的解决办法

SqlServer2008R2使用SQLCMD执行多个脚本

MS SQL SERVER执行大脚本文件时,提示“内存不足”的解决办法