# LINQ 中使用 SQL 的 IN 查詢筆數過多會遇到的問題 ###### tags: `被玩壞了` ## Linq SQL 的 In 使用 有兩個集合 EFTableA、ListB,要用 ListB 的 Id 作為條件去查詢 EFTableA 的資料 ``` EFTableA.Where( x => ListB.Select(b => b.Id).Contain( x.Id ) ); ``` ## 遇到什麼問題 ? 這時候 LINQ 轉到 SQL 語法時,會寫成 ``` Select * From TableA Where Id In ( 1, 2, 3, 4, ... ) ``` 可是如果 In 的條件非常多,上萬筆要比對,會造成 DB 的 查詢緩衝區記憶體不夠而 Crash ``` Select * From TableA Where Id In ( 1, 2, 3, 4, ... ,190000 ) ``` **※19 萬筆的時候遇到** ### 錯誤訊息 > 發生錯誤: 查詢處理器已用完內部資源而無法產生查詢計畫。 > 這是只有在極端複雜的查詢或者參考非常大量資料表或資料分割的查詢才會發生的稀有事件。 > 請簡化查詢。若認為收到此訊息有誤,請連絡客戶支援服務,以取得詳細資訊。 ## 該怎麼解 ? 若 In 的資料為 **「從資料表來」**,就可以避免這個問題 ※從資料表來的意思是 ``` Select * From TableA Where Id In (Select Id From TableB) ``` 使用 Store Procedure,將條件用成字串 => "1,2,3,4,5...,190000" 將 In 的部分轉為 **「從資料表來」**,使用字串分割函數 STRING_SPLIT **( SQL 2016 後適用 )** ``` Select * From TableA Where Id In ( Select * From STRING_SPLIT(IdString , ",")) ``` ※ [STRING_SPLIT ( string , separator ) separator 為欲分割的字串](https://docs.microsoft.com/zh-tw/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver15)