簡單測試linq to sql效能

2022-02-22 12:01:34 字數 3965 閱讀 6769

前些日子,做了乙個物業收費系統,cs模式,用到了linq to sql 技術,這是我第一次使用這個東東寫程式訪問資料庫,迷迷糊糊搞得一塌糊塗,當時有個同學他們找好的分頁元件,然後寫好了呼叫方法,由於時間比較急,而且第一次用,所以沒有怎麼研究就直接按照注釋使用他們寫好的分頁方法,然而開發過程中一直都對他們寫的方法有懷疑,會不會是一種投機取巧,胡編亂造的?後來我也做過一些簡單分析,我發現程式在業務邏輯層中每次都從資料庫中將資料全部讀取出來,然後迴圈將資料轉成特定的list,也就是遍歷整個資料集合,然後在顯示層中將list進行分頁,最後放到datagridview中,其中列名自動設定為類的屬性值,剛開始我還一直認為這樣的方法好方便啊,一下子全部生成了,直到程式馬上接近尾聲時,我發現程式的操作日誌記錄已經達到了4500條,每次開啟日誌管理介面時,程式都要載入上半天才能出來,我徹底對linq產生了懷疑,確切的說並不是對linq產生懷疑,而是分頁方法以及程式演算法產生了懷疑。

顯示層的分頁**部分:

1 datagridview.datasource = data.take(pagercontrol1.pagesize * pagercontrol1.pageindex).skip(pagercontrol1.pagesize * (pagercontrol1.pageindex - 1

)).tolist();,其中data是業務邏輯層獲取到的資料,業務邏輯層: 23

4var data = from d in

jx.logtable

5orderby

d.opertime descending

6where tflag.equals("

全部") ||

7 ((d.opertime >= t1 && d.opertime <= t2) && (d.opername.contains(content) ||d.userid.contains(content)))

8select

d;9 listitems = new list();

10foreach (var d in

data)

1120

return items;

此處不僅將所有資料全部讀取出來了,而且還遍歷了一遍,當資料達到4500條時就出現了卡頓現象,情況糟糕程度可想而知,好醜陋的**啊,而且程式牽扯到這個的地方簡直多的要命,如果要改動的話,一定是一場災難!

之前一直在忙,沒有時間去測試程式中所存在的問題以及如何能更高效的使用linq開發應用程式,今天擠出點時間來做了個小小的測試,這讓我重新對linq產生了興趣。

測試中的資料庫表仍然不改變,還是操作日誌表,不同的是我在該表中追加了更多的資料,總記錄數幾乎達到 110萬條,然後對這110萬條資料進行測試。具體測試如下:

當點選資料總條數時,彈出資料庫操作日誌表的總記錄數,點選載入資料時,對110萬條資料進行分頁 , 每頁10條,取第三頁的10條資料,點清空資料時,對**中載入的資料進行清空處理:

總條數如下:

首次執行,點選載入資料時,共耗時9100毫秒:

然後點選清空資料,再次點選載入資料時,共耗時2899毫秒:

之後重複測試,時間一直保持在3000毫秒左右,也就是3秒鐘,第二次點選後發現時間明顯加快了,3倍有餘,但是我想說的是這個速度還是非常非常慢的,因為表中的資料列所儲存的值很小,沒有什麼大的資料,為什麼會這麼慢呢?看**:

1 stopwatch sw = new

stopwatch();

2 sw.start(); //

開始計時34

var data = (from d in db.log select d).tolist();//

將資料全部查詢出來,並且tolist()

5 datagridview1.datasource = data.skip(20).take(10).tolist();//分頁6

7 sw.stop(); //

計時結束

8 messagebox.show("

共耗時:

"+sw.elapsedmilliseconds.tostring()+"毫秒"

); 9

然後我對**做了改變,如下:

1 stopwatch sw = new

stopwatch();

2 sw.start(); //

開始計時34

var data = (from d in db.log select d);//

只是寫好了查詢條件,注意此處

5 datagridview1.datasource = data.skip(20).take(10).tolist();//分頁6

7 sw.stop(); //

計時結束

8 messagebox.show("

共耗時:

"+sw.elapsedmilliseconds.tostring()+"

毫秒");

其實只是將上邊標紅的地方刪掉了,也就是tolist()部分, 採用控制變數法,其他資料和條件全部不做任何變動,看效果:

首次點選載入資料時,共耗時185毫秒: 

清空後,第二次點選載入資料時,共耗時39毫秒: 

之後測試,一直保持在40毫秒左右,差距為什麼會這麼大?

其實,linq執行過程的乙個重要特徵是延遲載入,就是知道要獲取資料時,才會進行計算。大家可能認為執行完var data = from db.log select d語句,然後在開始skip,take函式進行分頁,所有的值都會存到data中了,實際上,這條語句會延遲到foreach或者tolist()呼叫時才會執行。而var data = (from db.log select d)skip(20).take(10);語句執行完之後,程式只是生成了乙個比較完美的sql語句等待著執行,直到tolist()或者foreach出現,也就是一直等待程式需要獲取資料時才開始執行資料庫查詢,這就解釋了為什麼差距會這麼大的問題,同時也說明了linq進行分頁的效率還是非常可以的,在110萬條記錄下進行分頁最多需要大約200毫秒時間,最快大約40毫秒。

一定要注意:先分頁在獲取,而不是先獲取再分頁! 

於是,為了測試效率,我將資料追加到了220萬條,重新測試:

發現首次查詢時,共耗時195毫秒:

清空後,再次查詢,共耗時 37毫秒:

大功告成,經過測試,在linq分頁前不能呼叫讀取方法,應該分頁後再查詢...看來本次的專案開發可以大膽的繼續使用linq來運算元據庫了。當然,之前的物業管理系統,等忙完這一段時間,我得幫忙改改去,做人得負責任啊!!!

沒文化真可怕,這麼簡單的知識竟然現在才知道!

LINQ to SQL 簡單查詢

使用 linq 技術 進行查詢 步驟 1.先建立linq to sql 檔案 2.利用vs伺服器資源管理器連線上sql 把表拖到linq to sql 檔案中。code protected void page load object sender,eventargs e 編寫 注 建的linq to...

Linq to Sql簡單學習

從年前一直在做乙個專案,所有沒有時間來看書學習,最近終於有點空閒時間了,就想認真學習下在專案中用到的linq to sql。在做專案的過程中覺得linq很是神奇,語法簡單 直觀,對於我這個sql語句不是特別精通的菜鳥來說幫助甚大,所以就抽時間來好好學習學習linq的精妙。今天學習的內容是where的...

SQL效能 簡單測試

如何測試sql語句效能,提高執行效率 有時候我們經常為我們的sql語句執行效率低下發愁,反覆優化後,可還是得不到提高 那麼你就用這條語句找出你sql到底是在 慢了 示例 setstatistics io on setstatistics time ongo 你要測試的sql語句 select top...