我们有一个包含大约20列的表格,如下所示:
我们需要插入1000条记录,稍后再选择也会产生大约1000条记录。
尝试以两种方式完成插入:
两种情况下的插入都需要30秒以上。我们甚至尝试在干净的桌子上做这件事。怎么加速呢?
[对于正常的10列表,我们通过parallel.for在大约60秒内完成了200万条记录插入。]
选择(从SQL mgmt studio测试)返回2000条记录也需要超过30秒,即使在干净的表格中也是如此。
时间可变:
可变大小或上限固定大小是否会在列VARCHAR(SIZE)
中产生很大差异?
[磁盘速度很快(RAID?不确定)并专用于此数据库]
表架构:(没有PK)
varchar(50)
varchar(2)
smallint
varchar(2048)
int
int
varchar(2048)
varchar(MAX)
varchar(MAX)
varchar(MAX)
smallint
varchar(500)
varchar(500)
varchar(MAX)
smallint
smallint
bigint
bigint
bigint
varchar(2048)
smallint
varchar(MAX)
varchar(MAX)
varchar(2048)
datetime
索引:
索引在varchar(50)上,非唯一的非群集
SELECT语句:
select *
from table
where varchar(50) = 'value1'
and varchar(2) = 'value2'
and smallint = 'value3'
每个组合都是唯一的varchar(50)
有5个唯一的varchar(2)
条目,每个varchar(2)
还有1-3个smallint
条目。
答案 0 :(得分:5)
查看SqlBulkCopy课程。我之前做了一个比较,从.NET到SQL Server的高性能数据加载,比较SqlBulkCopy和SqlDataAdapter与底线,加载100,000行:
SqlDataAdapter:25.0729s
SqlBulkCopy:0.8229s
关于它的博客here
<强>更新强>
在SELECT性能方面,尝试对要查询的3个字段的索引 - 这将允许执行索引查找。目前,只有VARCHAR(50)上的索引,它将进行扫描。当您执行SELECT *以返回所有列时,它将不得不关闭并查找其他列中的其余数据,因为它们不会包含在索引中。这可能很昂贵,所以你应该考虑不做SELECT *而只返回你实际需要的列(如果你实际上并不需要它们)。您真正需要的那些,在SELECT中显式命名,然后您可以在WHERE子句中的3个字段上创建的索引中包含它们。 (参见INCSUDE的MDSN参考:http://msdn.microsoft.com/en-us/library/ms190806.aspx)
答案 1 :(得分:1)
加快查询速度:
不要将VARCHAR(50)
作为主要(因此:群集)密钥;使用更窄的东西,以及尺寸固定的东西。 INT IDENTITY
效果最佳
为什么你的桌子里有VARCHAR(8000)?这给桌子带来了很大的压力 - 为什么不做那些VARCHAR(MAX)呢?
分析您的查询并在可以编制索引的列上创建正确的非聚集索引