【问题标题】:Checklist towards optimal performance in a database import application在数据库导入应用程序中实现最佳性能的清单
【发布时间】:2009-01-12 22:48:11
【问题描述】:
我正面临一个旨在将大量数据导入 Microsoft SQL Server 2000 数据库的应用程序。该应用程序似乎需要很长时间才能完成,我怀疑应用程序设计存在缺陷。有人让我深入研究应用程序以查找并修复严重的瓶颈(如果有的话)。我想要一种结构化的方法来完成这项工作,并决定准备一份潜在问题清单以寻找。我有一些使用 SQL 数据库的经验,并且到目前为止已经写下了一些要寻找的东西。
但它对一些外部灵感也很有帮助。你们中的任何人都可以为我指出一些关于良好数据库架构设计和良好数据库应用程序设计的清单的好资源吗?
我计划针对以下主要主题制定清单:
- 数据库硬件 - 首先要证明服务器硬件合适?
- 数据库配置 - 下一步是确保配置数据库以获得最佳性能?
- 数据库架构 - 数据库架构是否设计合理?
- 数据库应用程序 - 该应用程序是否包含健全的算法?
【问题讨论】:
标签:
sql-server
database
database-design
【解决方案1】:
好的开始。以下是推荐的优先事项。
第一原则。除了源文件读取和 SQL 插入之外,导入应该很少或不做任何处理。其他处理必须在加载之前完成。
应用程序设计是#1。应用程序是否在尝试加载之前尽可能多地处理平面文件?这是大型数据仓库加载的秘诀:离线准备,然后批量加载行。
-
数据库架构是#2。你有正确的表和正确的索引吗?负载不需要任何索引。大多数情况下,您希望删除并重建索引。
负载最好不需要任何触发器。所有触发的处理都可以离线完成以准备加载文件。
加载最好不要作为存储过程来完成。您想使用 Microsoft 的简单实用程序来批量加载行。
配置。很重要,但比架构设计和应用程序设计要少得多。
硬件。除非你有钱烧钱,否则你不会走多远。如果——在所有其他事情之后——你可以证明硬件是瓶颈,那就花钱吧。
【解决方案2】:
我要添加到列表中的三个项目:
- 批量插入 - 您是使用批量提供程序(即 BCP 或 SqlBulkCopy)还是通过单独的 INSERT/UPDATE 语句导入数据?
- 索引 - 您的目标表上有索引吗?可以在导入之前删除它们,然后再重新构建它们吗?
- 锁定 - 尝试导入数据时是否发生争用?
【解决方案3】:
您忽略了我开始寻找的第一个地方:用于导入数据的技术。
如果应用程序正在插入单行,那有什么原因吗?是使用 DTS 还是 BULK INSERT 还是 BCP?它是加载到临时表还是带有触发器的表?它是分批加载还是尝试加载并提交整个批次?行中是否有大量的转换或数据类型转换?是否将数据广泛转换为不同的架构或模型?
我不会担心 1 和 2,直到我看到所使用的 ETL 技术是否可靠,并且如果他们将数据导入现有架构,那么您将没有太多空间来更改任何与3.关于import和4,我不喜欢在load部分对数据做太多算法。
为了在最一般的情况下获得最佳性能,请加载到具有良好可靠的基本类型转换和当时完成的异常的平面暂存表(使用 SSIS 或 DTS)。对于非常大的数据(例如每天加载数百万行),我会加载 100,000 或 1,000,000 个记录批次(这在 BCP 或 SSIS 中很容易设置)。任何派生列要么在加载时创建(SSIS 或 DTS),要么在 UPDATE 之后立即创建。运行异常、验证数据并创建约束。然后将数据作为一个或多个事务的一部分处理到最终架构中 - 维度或实体的 UPDATE、INSERT、DELETE、GROUP BY 等等。
显然,这也有例外,这在很大程度上取决于输入数据和模型。例如,在输入中使用 EBCDIC 打包数据时,在加载阶段没有可靠的基本类型转换之类的东西,这会导致您的加载更加复杂和缓慢,因为必须更大量地处理数据。
使用这种整体方法,我们让 SQL 做它擅长的事情,并让客户端应用程序(或 SSIS)做它们擅长的事情。