INSERT INTO在SQL Server 2012中随着时间的推移变得慢得多

前端之家收集整理的这篇文章主要介绍了INSERT INTO在SQL Server 2012中随着时间的推移变得慢得多前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们有一个非常大的数据库WriteDB,它存储原始交易数据,我们使用这个表来快速写入.然后使用sql脚本,我将WriteDB中的数据导入到相对相同的表中的ReadDB中,但扩展了一些额外的值关系.导入脚本是这样的:
TRUNCATE TABLE [ReadDB].[dbo].[Price]
GO
INSERT INTO [ReadDB].[dbo].[Price]
SELECT a.*,0 as ValueUSD,0 as ValueEUR
from [WriteDB].[dbo].[Price] a
JOIN [ReadDB].[dbo].[Companies] b ON a.QuoteId = b.QuoteID

所以最初大约有130万.此表中的行(~50GB).每天他们中的一些人都会添加,其中一些会发生变化,所以现在我们决定不复杂逻辑,只重新导入所有数据.由于某种原因,由于某些原因,这个脚本的工作时间越来越长,几乎相同的数据量.首先运行它需要〜1小时,现在它已经花了3小时

另外sql Server导入后工作也不顺利.导入(或在其中)如果我尝试运行不同的查询,即使是最简单的,它们通常也会因超时错误而失败.

这种不良行为的原因是什么以及如何解决这个问题?

解决方法

一种理论是,您的第一个50GB数据集已填充可用于缓存的内存.截断表后,您的缓存现在实际上是空的.这种交替行为使得高速缓存的有效使用变得困难并且导致大量的高速缓存未命中/增加的IO时间.

考虑以下事件序列:

>您将初始数据集加载到WriteDb中.在加载操作期间,WriteDb中的页面被缓存.内存争用非常少,因为只有一个数据集副本和足够的内存.
>您最初填充ReadDb.填充ReadDb所需的页面(WriteDb中的数据)已经在很大程度上被缓存.磁盘需要的读取次数较少,您的IO时间可专用于为ReadDb写入插入的数据. (这是你的第一次快速运行.)
>您将第二个数据集加载到WriteDb中.在加载操作期间,没有足够的内存来缓存ReadDb中的现有数据和写入WriteDb的新数据.这种内存争用导致WriteDb缓存的页面更少.
>您截断ReadDb.这会使大部分缓存失效(即缓存的50GB ReadDb数据).
>然后,您尝试第二次加载ReadDb.在这里你只有很少的WriteDb缓存,所以你的IO时间在读取WriteDb页面(你的查询)和写入ReadDb页面(你的插入)之间分配. (这是你的第二次慢跑.)

您可以通过比较第一次和第二次加载操作期间的sql Server缓存未命中率来测试此理论.

提高性能的一些方法可能是:

>为ReadDb / WriteDb使用单独的磁盘阵列以提高并行IO性能.>增加可用缓存(服务器内存量)以适应ReadDb WriteDb的总大小并最大限度地减少缓存未命中.>通过使用MERGE语句而不是一次转储/加载50GB数据,最大限度地减少每个加载操作对现有缓存页面的影响.

原文链接:https://www.f2er.com/mssql/76732.html

猜你在找的MsSQL相关文章