0

我们构建了一个可用于创建数据仓库的 C# .NET 系统。该系统采用选定的数据库并针对这些数据库运行脚本以创建组合的数据库/仓库。

现在,我将三个数据库编译成一个数据库,并且我从每个数据库中复制两个表(表 [XI] 和表 [XII] - 它们具有一对多关系,但在副本/ INSERT INTO)。脚本运行的数字和每个表的相关大小如下:

执行的脚本由 30 个 SQL 查询组成。

  1. 数据库A

    Table [XI]  29,026 Rows (size 20,128Kb).
    Table [XII] 531,958 Rows (size 50,168Kb).
    Time taken for entire script: 1.51s.
    
  2. 数据库B

    Table [XI]  117,877 Rows (size 17,000Kb).
    Table [XII] 4,000,443 Rows (size 512,824Kb).
    Time taken for entire script: 2.04s.
    

这些都运行良好且快速。下一个几乎与第一个大小完全相同,但需要 40 倍的时间!

  1. 数据库C

    Table [XI]  29,543 Rows (size 20,880Kb).
    Table [XII] 538,302 Rows (size 68,000Kb).
    Time taken for entire script: 44.38s.
    

我无法弄清楚为什么这需要这么长时间。我使用过 SQL Server Profiler 和性能监视器,但我无法确定性能发生如此巨大变化的原因。

用于进行更新的查询是动态的,并显示在此问题的底部 - 由于明确引用了所需列,因此它很大。我的问题是;什么可能导致执行时间过度增加?

任何线索将不胜感激。

SQL:

DECLARE @DbName NVARCHAR(128);
SET @DbName = (SELECT TOP 1 [DbName] 
               FROM [IPACostAdmin]..[TmpSpecialOptions]);
DECLARE @FilterSql NVARCHAR(MAX);
SET @FilterSql = (SELECT TOP 1 [AdditionalSQL] 
                  FROM [IPACostAdmin]..[TmpSpecialOptions]);
DECLARE @SQL NVARCHAR(MAX);
DECLARE @SQL1 NVARCHAR(MAX);
DECLARE @SQL2 NVARCHAR(MAX);
SET @SQL1 = 
    'INSERT INTO [' + @DbName + ']..[Episode] 
        ([Fields1], ..., [FieldN])'; 
SET @SQL2 = 
'SELECT 
     [Fields1], ..., [FieldN] 
FROM [B1A] ' + @FilterSql + ';'; 
SET @SQL = @SQL1 + @SQL2;
EXEC(@SQL);
GO

注意:为了清楚起见,我将动态 SQL 拆分为@SQL1@SQL2。另请注意,由于空间以及它在很大程度上是多余的事实,我没有显示所有列。

编辑1。

1. 数据库在同一台服务器上。

2. 包括日志在内的数据库文件位于同一驱动器的同一目录中。

3. 此时源数据库(DatabaseA/B/C)或数据仓库数据库上没有设置主/外键或约束INSERT INTO

编辑2。我在管理工作室运行了上述查询,花了 5 秒!?

编辑3。我添加了一个临时CLUSTERED INDEX的,希望这将有助于这个查询,这也没有帮助。

4

2 回答 2

1

一些信息会很高兴知道:

1:数据库在同一台服务器上?

2:A和C的情况下db文件和日志文件在同一个驱动器上?

(有一次我遇到了两个数据库的问题,其中一个在 SSD 驱动器上,另一个在 HDD 上。这是读取数据的问题)

3:关于碎片的数据库统计?(表没有约束,但定义了索引?)

于 2012-09-24T10:14:41.653 回答
0

这是由DELETE在前面的CREATE CLUSTERED INDEX查询有时间更新整个表之前运行的查询引起的。解决方案是使用BEGIN TRANSACTIONandCOMMIT关键字。这会强制 SQL Server在尝试任何其他操作之前完成索引。

CREATE CLUSTERED INDEX请注意,只有在使用修改现有表的动态 SQL 语句进行查询时,才可能出现此问题。

我希望这对其他人有帮助。

于 2012-10-04T10:42:20.733 回答