這個還真是復雜,看了看微軟的文檔,有些根本就看不懂,有些能看懂,但對我這種菜鳥也不會去用。
無從下手啊,前面放了幾個鏈接,挨個試試吧。
一、顯式打開連接
這個我測試過,有些時候,需要我們顯示打開連接,有時不用。
1、.SaveChanges()
沒寫錯吧,嘿嘿。
這個不需要關注連接的問題,因為不管之前你無論是修改、刪除、新增,只有一個SaveChanges(),一定是只用一個鏈接,並且系統還會自動使用事務。
2、查詢
增刪改一個SaveChanges()就搞定了,可查詢不是。
同時需要查詢多個數據的情況並不少見,比如EasyUI 的 DataGrid,它不僅要使用數據,還需要總行數,這時,就是兩個查詢,兩個查詢你雖然可以挨着寫,可實際情況卻是:
打開連接
查詢
關閉連接
打開連接
查詢
關閉連接
具體這樣影響多大性能不清楚,連接雖然在連接池中,但打開一次,應該是建立一次TCP連接,總要消耗一些性能。
針對這種情況,就可以顯示打開連接了:
使用using或try,畢竟涉及到連接了嗎,總要將它關閉,然后:
.Open()
查詢
查詢
.Close()或.Dis…()
二、延遲加載
不要使用延遲加載,要一次把需要的數據讀取出來。特別是在循環中使用延遲加載,每次都讀取一次數據庫,對性能影響非常大。
有主外鍵關系的使用.Include,沒有的使用.Join。
三、盡可能的使用.Select
記得以前學數據庫時,老師總是講,用什么字段select什么字段,我想,這里應該也是一樣,僅查詢需要的字段,查詢的字段少,在數據庫執行查詢時應該快一點,EF中應該也一樣吧,字段少需要賦值的東西就少,應該也會快。
至於select到新的實體類,還是到var,應該看復用程度和與其它功能(比如界面生成)的相關程度,如果僅用一次,var就很好。
當然,如果需要傳遞,就不能使用var,要使用 dynamic。
四、應用服務器查詢還是數據庫服務器查詢
直白點也就是先.ToList()還是后.ToList(),讓然這里只是舉例,只是想說明.ToList()才會到數據庫查詢,有些情況下並不需要.ToList()。
這個個人認為還是應該在數據庫服務器查詢,比較好規范開發人員行為,因為有些數據量比較大,你不能都查詢到應用服務器在select/where吧,這樣可能性能更差。如果你應用服務器比較空閑,可以移到數據庫中一個嗎。當然有些老的應用,架子搭在那了,就需要視情況而定了。
引用別人的文章來說明這個問題:
http://www.cnblogs.com/jake1/archive/2013/04/25/3043664.html
- 分頁的時候,盡量在數據庫里面去分頁.在我實際中的項目,我就發現我同事由於他不了解EF屬性,它的分頁都是做在內存中分頁.下面請看他的代碼.
queryToList().Skip((pageInfo.PageIndex - 1) * pageInfo.PageSize).Take(pageInfo.PageSize);
像上面的語句,他會先把數據從數據庫中查出來,然后才分頁.
正確的寫法應如下:
query.Skip((pageInfo.PageIndex - 1) * pageInfo.PageSize).Take(pageInfo.PageSize).ToList();這樣才會在數據庫中分頁.
上面這個示例非常典型,無論怎樣,分頁都應該在數據庫中,你把很多數據都讀取到應用服務器的內存中再取其中的10條記錄,真是有點小題大做了。
五、太復雜的查詢使用存儲過程
如果涉及多個表的關聯,最好使用存儲過程。EF雖然也能實現,但其生成的sql恐怕和預想的要差很遠。
六、主外鍵
能使用主外鍵的,盡可能的使用主外鍵,這樣無論是EF還是數據庫,性能都會有所提高。當然太復雜的還是應該使用存儲過程。
七、預生成視圖
這個操作還很麻煩,當然只是第一次訪問時會影響性能,對一些訪問量不大的,不用也罷,畢竟你發布上去之后,有可能第一次訪問的就是你自己。
八、NoTracking
這個按微軟說性能影響不大,多數情況下我們也不需要它跟蹤,所以,加上算了。
九、using
十、Exists
在博客中看到的,感覺很有用
http://www.cnblogs.com/lori/p/3457430.html
EF架構~在ef中支持IQueryable級別的Contains被翻譯成了Exists,性能可以接受!
Entityframeworks很聰明
不錯,非常不錯!ef里的contains比linq to sql里的contains有了明顯的提升,事實上,是在進行SQL語句翻譯上有所提升,在linq to sql里不支持iqueryable的contains集合,它只支持本地集合進行contains,而本地集合的contains會被.net翻譯成sql語句是where in (...),即集合有多個元素,在in里就會被列舉多少次,這個在性能上是非常低下的,不提倡的,而且它還有長度限制,最多本地集合在linq to sql里是2000多個元素。
ef在這點上表示不錯,它為了防止你使用低下的查詢,它杜絕你在linq語句中去ToList()對象,這是不錯的選擇,對於EF中的contains的用法,我們一般是分兩步,第一查詢出要列舉的結果集,但不要ToList(),第二是使用contains語句,當EF把它發到SQL端時,這個語句被翻譯成了exist,我們知道,這種查詢的性能一定是比where in強的,不說SQL本身就說網絡傳輸,它也一定比前者省了不少,呵呵。
Entityframeworks中正確使用Contains語句的Demo
錯誤的
var linq = (from data1 in GetUser().Where(i => i.UserID <= 50) select data1.UserID).ToList(); var linq2 = GetUser_StudyRecord().Where(i => linq.Contains(i.UserID.Value)).ToList();SQL語句截圖
正確的
var linq = (from data1 in GetUser().Where(i => i.UserID <= 50) select data1.UserID);//IQueryable<int>,一個查詢計划 var linq2 = GetUser_StudyRecord().Where(i => linq.Contains(i.UserID.Value)).ToList();SQL語句截圖
對我這種散修來說,未查找更多實用的,路過的老大看到有錯誤指點一下