国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

asp.net下數據庫操作優化一例

2024-07-10 13:25:38
字體:
來源:轉載
供稿:網友
下面是最初實現的代碼,其中 LargerResultProcessor 是一個基類,負責遍歷泛型參數 T 所指向的數據庫表,并以每頁 100 項的方式分頁,并對每一項調用 ProcessItem 函數,而子類只需實現 ProcessItem 函數即可:

復制代碼 代碼如下:


public class ItemRenameCompanyId : LargerResultProcessor<Item>
{
protected override void ProcessItem(Item item)
{
const string template1 = @"select top 1 shop_id from orders where Item_id = '{0}'";
var sql1 = string.Format(template1, item.Id);
const string template2 = @"update Items set shop_id={0} where id = {1};
update skus set shop_id={0} where item_id = {1};";
try
{
var obj = DbEntry.Context.ExecuteScalar(sql1);
var sql2 = string.Format(template2, long.Parse(obj.ToString()), item.Id);
DbEntry.Context.ExecuteNonQuery(sql2);
}
catch (Exception exception)
{
Logger.Default.Warn(exception + item.Id.ToString());
}
}
}


上面這段代碼,邏輯比較簡單,針對每一項,使用 Select 語句取出 Shop_Id,并且執行 Update,只是有個問題,就是執行速度比較慢,對于我們 6 萬左右 Item,4 萬左右 Sku,99 萬左右 Order 的表,需要執行約 40 分鐘,才能轉換完畢。
這些代碼,雖然是一次性操作,但是對于運行系統,停機時間越短越好,于是進行一些優化工作,數據庫對于大量重復的語句,如果使用參數的方式,因為可以避免對于語句的重復解析工作,所以速度會快一些,按照這個思路,簡單的修改如下:

復制代碼 代碼如下:


public class ItemRenameCompanyId : LargerResultProcessor<Item>
{
protected override void ProcessItem(Item item)
{
const string template1 = @"select top 1 shop_id from orders where Item_id = @id";
const string template2 =
@"update Items set shop_id=@sid where id = @id;
update skus set shop_id=@sid where item_id = @id;";
try
{
var sql1 = new SqlStatement(template1, new DataParameter("@id", item.Id));
var sid = Convert.ToInt64(DbEntry.Context.ExecuteScalar(sql1));
var sql2 = new SqlStatement(template2, new DataParameter("@sid", sid), new DataParameter("@id", item.Id));
DbEntry.Context.ExecuteNonQuery(sql2);
}
catch (Exception exception)
{
Logger.Default.Warn(exception + item.Id.ToString());
}
}
}


測試這個程序,大概 25 分鐘可以完成轉換。有一些提高,不過,我們真正要修改的數據量并不大,一共只有 6 萬 加 4 萬 大約 10 萬條數據,所以 25 分鐘還是有些長了。簡單分析后,Orders 是最大的表,如果整體速度慢,則導致速度慢最大的可能因素,應該是查詢 Orders,所以稍換一個思路,提前把 Item_Id 和 Shop_Id 的對應關系查找出來,放到內存里,從而避免每次 ProcessItem 都要進行 Orders 表的查詢。至于內存里的數據,本來準備用 Dictionary 的,后來一想,Id 都是 long 型的數據,而且不能算“稀疏”矩陣,基本可以稱為“稠密”矩陣,所以,直接用數組應該是速度更快,所以先查詢出 Items 的最大 Id,用于設置數組大小,再按索引賦值即可:

復制代碼 代碼如下:


public class ItemRenameCompanyId : LargerResultProcessor<Item>
{
private readonly long[] _dic;
public ItemRenameCompanyId()
{
var count = Convert.ToInt64(DbEntry.Context.ExecuteScalar("select top 1 Id from items order by id desc")) + 10;
_dic = new long[count];
var sql =
new SqlStatement(
"select items.id as xiid,orders.shop_id as xsid from items inner join orders on orders.item_id = items.id group by items.id,orders.shop_id")
{SqlTimeOut = 300};
dynamic list = DbEntry.Context.ExecuteDynamicList(sql);
foreach(dynamic row in list)
{
_dic[row.xiid] = row.xsid;
}
}
protected override void ProcessItem(Item item)
{
const string template2 =
@"update Items set shop_id=@sid where id = @id;
update skus set shop_id=@sid where item_id = @id;";
try
{
var sid = _dic[item.Id];
var sql2 = new SqlStatement(template2, new DataParameter("@sid", sid), new DataParameter("@id", item.Id));
DbEntry.Context.ExecuteNonQuery(sql2);
}
catch (Exception exception)
{
Logger.Default.Warn(exception + item.Id.ToString());
}
}
}


再測試這一段程序,運行 70 秒就完成了數據轉換,另外,查詢對應關系那一句 SQL,因為針對的是剛恢復的數據庫,所以用了大概 3、40 秒,實際使用查詢管理器,在運行中的數據庫執行那一句 SQL,只需要 1 秒左右就可以完成,所以,估計在實際轉換的時候,3、40 秒就可以完成轉換了。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 肇东市| 和田市| 南城县| 和龙市| 乐至县| 阿勒泰市| 成武县| 伊通| 四川省| 红原县| 礼泉县| 建湖县| 遵义县| 叙永县| 平江县| 长武县| 绵阳市| 河源市| 威信县| 宕昌县| 千阳县| 绍兴市| 广灵县| 卓尼县| 宿松县| 方山县| 库车县| 永川市| 繁峙县| 韶山市| 乐亭县| 上杭县| 昭通市| 兴安县| 信宜市| 苍溪县| 游戏| 安乡县| 高台县| 荆门市| 乌拉特前旗|