【发布时间】:2013-10-30 21:55:05
【问题描述】:
我有一个包含大量数据(数百万行)的数据库,并且在白天更新大量数据,我有这个数据库的备份用于报告,所以获取数据报告不会影响主数据库的性能。
为了将备份数据库与主数据库同步,我编写了一个 Windows 服务,它查询主数据库并将新数据插入备份数据库...每次查询从主数据库获取 5000 行...
编辑:
查询如下:
const string cmdStr = "SELECT * FROM [RLCConvertor].[dbo].[RLCDiffHeader] WHERE ID >= @Start and ID <= @End";
代码如下:
using (var conn = new SqlConnection(_connectionString))
{
conn.Open();
var cmd = new SqlCommand(cmdStr, conn);
cmd.Parameters.AddWithValue("@Start", start);
cmd.Parameters.AddWithValue("@End", end);
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
while (reader.Read())
{
var rldDiffId = Convert.ToInt32(reader["ID"].ToString());
var rlcDifHeader = new RLCDiffHeader
{
Tech_head_Type = long.Parse(reader["Tech_head_Type"].ToString()),
ItemCode = long.Parse(reader["ItemCode"].ToString()),
SessionNumber = long.Parse(reader["SessionNumber"].ToString()),
MarketFeedCode = reader["MarketFeedCode"].ToString(),
MarketPlaceCode = reader["MarketPlaceCode"].ToString(),
FinancialMarketCode = reader["FinancialMarketCode"].ToString(),
CIDGrc = reader["CIDGrc"].ToString(),
InstrumentID = reader["InstrumentID"].ToString(),
CValMNE = reader["CValMNE"].ToString(),
DEven = reader["DEven"].ToString(),
HEven = reader["HEven"].ToString(),
MessageCodeType = reader["MessageCodeType"].ToString(),
SEQbyINSTandType = reader["SEQbyINSTandType"].ToString()
};
newRLCDiffHeaders.Add(rldDiffId, rlcDifHeader);
}
conn.Close();
}
但是当我启动服务时......主数据库的性能变差了......代码效率不高?有没有更好的办法?因为我搜索并发现dataReader 最适合这种情况……还是我应该使用DataTable 和SqlDataAdapter?
【问题讨论】:
-
不,使用
SqlDataAdapter绝对不是一种更有效的做事方式。我推荐的一件事 - 尝试更小的尺寸...... 5000 行 可以 导致 SQL Server 执行 lock escalation 并锁定整个表 - 而不是拥有行 -水平锁。使用 2000 行或类似的内容。 -
另外 - 你看过 SQL Server replication 吗?它会为你完成所有这些工作 - 它就在产品中,已针对最高性能进行了调整....
-
对于数据库性能,发送到 db 的查询比使用 DataTable 或 DataReader 更重要。可以使用 nolock 关键字读取未提交的数据。
-
对我来说,这个问题最有趣的部分是
cmdStr的内容——没有它,我们所拥有的只是“我有一些从数据读取器读取的代码”——也就是说, 本身很好,也不是低效的。但是:您正在运行什么命令,以及您运行它的频率如何?我的假设是这里的任何性能损失都与在数据库服务器上花费的时间有关-但您应该对其进行分析以找出-没有任何迹象表明.NET性能问题 -
@Paridokht
ID上是否有聚集索引?回复nolock- 那将是:SELECT * FROM [RLCConvertor].[dbo].[RLCDiffHeader] with (nolock) WHERE ID >= @Start and ID <= @End- 如果您受到阻塞的不利影响,这将避免问题,但意味着您可能会进行脏读
标签: c# sql dataset sqldatareader sqldataadapter