1. 程式人生 > >那條linq語句為啥這麼慢

那條linq語句為啥這麼慢

目前所在的專案大量使用了linq,結果有個地方出現了嚴重的效能問題。一個統計需要3、40秒。頭頭焦頭爛額之際,也讓我看看。

我向來喜歡效能調優,自詡編碼極為注重效能。曾幾何時,也動不動就把效能掛在嘴邊。總之,我貌似是一個性能磚家。

不過,對於這條linq,我陰溝翻船,搞不定。一來我半路殺入,不瞭解情況;二來我看不懂那些linq。

我想到的切入點,是監控資料庫執行的sql,看看問題出在哪裡。

資料庫是oracle的。如果是sql server,有圖形化的介面profile侍候,但oracle的話,plsql工具有個SQL 跟蹤,但好像變灰了,用不了。可以查詢檢視V$SQL。

用sys登入,執行如下語句:

select sql_text,sql_fulltext,cpu_time,elapsed_time,first_load_time,last_load_time,last_active_time
from v$sql
where last_active_time is not null
and module='w3wp.exe' --來自於IIS
and service='ORCL' --指定資料庫例項名稱
order by last_active_time desc --按時間倒序排

檢視V$SQL欄位極多,涉及到時間的有好幾個。first_load_time,last_load_time這些不宜用來考察執行的時間點。因為看上去這裡面涉及到快取。一條SQL語句,如果沒有變化,那麼一次載入,可以重複使用很久。

我運行了這條查詢語句,可以看到所有的SQL。問題是,除錯那個linq,卻看不到有啥SQL出現。真奇怪啊。

後來頭頭自己搞定了。原因是參與這條linq運算的物件是一個IEnumable<>,改成IQueryable<>就可以了。估計是IEnumable<>物件的話,系統會自動ToList(),將資料獲取到記憶體裡,然後參與運算;而IQueryable<>的話,則最後編譯成sql到資料庫執行,這時過濾條件什麼的會起作用,速度當然快了。這也是為何那條LINQ不見有SQL產生的原因。

但是,IQueryable 是繼承 IEnumable 的。這聽上去有點詫異。