SQL SERVER 錯誤:查詢處理器用盡了內部資源,無法生成查詢計划。這種情況很少出現,只有在查詢極其復雜或引用了大量表或分區時才會出現。請簡化查詢。如果您認為該消息的出現純屬錯誤,請與客戶支持服務部門聯系,了解詳細信息。


排除錯誤外,基本就是查詢語句確實消耗了過多的資源

這次遇到這個錯誤是因為在 where 語句中 in 了過多的數據(大概 10000+)

需要調整一下查詢邏輯了

根據不同的業務邏輯可能有不同的調整方式,這里介紹一個用了感覺還比較有效的方法

就是在查詢過程中將需要 in 查詢的所有數據插入臨時表,然后通過 join 臨時表或子查詢的方式來達到同樣的效果

如果是用 ef + linq 查詢的話,可能需要在數據庫中創建一個固定的臨時表,通過構建一個查詢批次 id 來應對並發

CREATE TABLE [dbo].[temp_table](
    [QueryId] [uniqueidentifier] NOT NULL,
    [DataId] [bigint] NOT NULL
)

在代碼中,通過批量插入來提高效率

private static Guid SetTempTable(IEnumerable<long> dataIds)
{
    var temp_table = new DataTable("temp_table");
    temp_table.Columns.Add("QueryId", typeof(Guid));
    temp_table.Columns.Add("DataId", typeof(long));
    var queryId = Guid.NewGuid();
    foreach (var recordId in dataIds)
    {
        temp_table.Rows.Add(queryId, recordId);
    }

    SqlHelper.BulkCopyDataTable(temp_table, temp_table.TableName);

    return queryId;
}

使用 join 查詢

var query = from user in user_table join id in temp_table on user.UserId equals id.DataId select user

使用完成后直接批量刪除

private static void ClearTempTable(Guid queryId)
{
    SqlHelper.ExecuteNonQuery("DELETE FROM temp_table WHERE QueryId = @QueryId", new SqlParameter("@QueryId", queryId));
}

除了對已經查不出來的 in 條件外,對能查出來的查詢速度提升也很明顯~

參考:https://stackoverflow.com/questions/16360236/ef-query-where-list-contains-a-lot-of-elements


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM