问题描述
我们正在使用Microsoft SQL Server 2016(SP2-CU12)(KB4536648)-13.0.5698.0(X64)2020年2月15日01:47:30版权所有(c)Windows Server 2012上的Microsoft Corporation标准版(64位) R2 Standard 6.3(内部版本9600:)
我们有一个表,其中有超过一百万行,其中有很多大字段(nvarchar(max),bigint,uniqueidentifier)。我们在桌上使用变更追踪。多线程Web应用程序以及许多其他多线程应用程序也可以访问该表。
现在在其中一个应用程序中,开发人员执行了以下代码。
public IEnumerable<MyObject> GetRecords(long trackingKey)
{
using(SqlConnection conn = new SqlConnection(_connectionString))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
StringBuilder builder = new StringBuilder();
builder.Append("SELECT Columns INTO #TEMP FROM CHANGETABLE(CHANGES BigTable,@TrackingKey) AS CT JOIN BigTable t ON t.Key=CT.Key WHERE Conditions=@Conditions
SELECT * FROM #TEMP ");
cmd.CommandText = builder.ToString();
cmd.Parameters.Add...;
using(SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
yield return (MyObject)ExecuteMyReader(reader);
}
}
}
}
}
在“ ExecuteMyReader”内部,他们正在从阅读器中读取内容,并对该行执行对另一个表的第二次查询(平均大约需要150毫秒才能执行)。
在SQL Query中查询变更表似乎在从变更跟踪表获取结果时锁定了该表。这就是为什么开发人员在执行最终SELECT查询之前将结果存储在临时表中的原因。 (为了尽量避免死锁。)
问题#1:在第二个SELECT查询完成时,更改跟踪表的锁定是否将被保留?还是在结果进入#Temp表后立即发布?
问题2:为阅读器提供收益与将所有内容都存储在变量中的经典方法有所不同吗?例如,是否会更快地释放RAM和#Temp表?
问题3:从多线程角度来看,如果其他查询尝试同时访问同一张表,是否有更好的方法来避免死锁? (有收益,没有收益的经典方法)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)