我們有一個使用 Azure 中托管的 EF 6 的 asp.Net 應用程式。除了某些罕見的操作外,資料庫大部分時間都以大約 20% 的 DTU 使用率運行。這些幾乎就像 Excel 格式的資料庫轉儲,比如擁有過去 X 年的所有訂單等,(高級)用戶可以觸發,然后通過電子郵件獲得結果。
問題是這些查詢用完所有 DTU,整個應用程式進入爬行狀態。我們想限制這些非關鍵查詢,因為這是否需要 10-15 分鐘更長的時間并不重要。
谷歌搜索我找到了減少 DEADLOCK_PRIORITY 的選項,但這不會解決用完所有資源的問題。
感謝您提供任何指示、想法或解決方案。
uj5u.com熱心網友回復:
優化將很難,因為它或多或少是一個資料庫轉儲。
Azure SQL 資料庫沒有可用的資源調控器,因此您必須在代碼中處理此問題。
Azure SQL 資料庫在 READ COMMITTED SNAPSHOT 模式下運行,因此減慢從表(或任何流查詢計劃)轉儲資料的會話應減少其 DTU 消耗,而不會對其他會話產生不利影響。
為此,在讀取查詢結果的回圈中放置等待,IEnumerable<TEntity>從 LINQ 查詢SqlDataReader回傳或從 ADO.NET 回傳SqlCommand。
但是您必須直接回圈流式傳輸結果。首先使用無法復制的查詢結果到記憶體IQueryable<TEntity>.ToList()或者DataTable.Load(),SqlDataAdapter.Fill()等等,因為這將盡可能快地閱讀。
例如
var results = new List<TEntity>();
int rc = 0;
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
rc ;
var e = new TEntity();
e.Id = dr.GetInt(0);
e.Name = dr.GetString(1);
// ...
results.Add(e);
if (rc%100==0)
Thread.CurrentThread.Sleep(100);
}
}
或者
var results = new List<TEntity>();
int rc = 0;
foreach (var e in db.MyTable.AsEnumerable())
{
rc ;
var e = new TEntity();
e.Id = dr.GetInt(0);
e.Name = dr.GetString(1);
// ...
results.Add(e);
if (rc%100==0)
Thread.CurrentThread.Sleep(100);
}
為了獲得額外的積分,請使用異步等待并將結果直接流式傳輸到客戶端,而無需在記憶體中進行批處理。
或者,您可以使用命名的Application Locks將可以同時執行轉儲的會話數量限制為一個,或每個表一個等。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/313311.html
標籤:天蓝色 实体框架 azure-sql-数据库
