我们有一个非常大的数据库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)。每天他们中的一些人都会添加,其中一些会发生变化,所以现在我们决定不会复杂化逻辑并重新导入所有数据。出于某种原因,由于某种原因,这个脚本的工作时间越来越长,几乎相同数量的数据。首先运行需要~1h,现在已经花了3h
导入工作后的SQL Server也不行。导入(或在其中)如果我尝试运行不同的查询,即使是最简单的查询也经常会因超时错误而失败。
这种不良行为的原因是什么以及如何解决这个问题?
答案 0 :(得分:5)
一种理论是,您的第一个50GB数据集已填充可用于缓存的内存。截断表后,您的缓存现在实际上是空的。这种交替行为使得缓存的有效使用变得困难并且导致大量的缓存未命中/增加的IO时间。
考虑以下事件序列:
您可以通过比较第一次和第二次加载操作期间的SQL Server缓存未命中率来测试此理论。
提高效果的一些方法可能是:
MERGE
语句而不是一次转储/加载50GB数据,最大限度地减少每个加载操作对现有缓存页面的影响。