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