關于Net開發中一些SQLServer性能優化的建議

一、 ExecuteNonQuery和ExecuteScalar

對數據的更新不需要返回結果集,建議使用ExecuteNonQuery。由于不返回結果集可省掉網絡數據傳輸。它僅僅返回受影響的行數。如果只需更新數據用ExecuteNonQuery性能的開銷比較小。

ExecuteScalar它只返回結果集中第一行的第一列。使用 ExecuteScalar 方法從數據庫中檢索單個值(例如id號)。與使用 ExecuteReader 方法, 返回的數據執行生成單個值所需的操作相比,此操作需要的代碼較少。

只需更新數據用ExecuteNonQuery.單個值的查詢使用ExecuteScalar 。

二、 SqlDataRead和Dataset的選擇

Sqldataread優點:讀取數據非常快。如果對返回的數據不需做大量處理的情況下,建議使用SqlDataReader,其性能要比datset好很多。缺點:直到數據讀完才可close掉于數據庫的連接 。(SqlDataReader 讀數據是快速向前的。SqlDataReader 類提供了一種讀取從 SQL Server 數據庫檢索的只進數據流的方法。它使用 SQL Server 的本機網絡數據傳輸格式從數據庫連接直接讀取數據。DataReader需及時顯式的close。可及時的釋放對數據的連接。)

Dataset是把數據讀出,緩存在內存中。缺點:對內存的占用較高。如果對返回的數據需做大量的處理用Dataset比較好些可以減少對數據庫的連接操作。優點:只需連接一次就可close于數據庫的連接。

一般情況下,讀取大量數據,對返回數據不做大量處理用SqlDataReader.對返回數據大量處理用datset比較合適.對SqlDataReader和Dataset的選擇取決于程序功能的實現。

數據綁定的選擇

三、 數據的綁定DataBinder

一般的綁定方法<%# DataBinder.Eval(Container.DataItem, "字段名") %> 用DataBinder.eval 綁定不必關心數據來源(Dataread或dataset)。不必關心數據的類型eval會把這個數據對象轉換為一個字符串。在底層綁定做了很多工作,使用了反射性能。正因為使用方便了,但卻影響了數據性能。

來看下<%# DataBinder.Eval(Container.DataItem, "字段名") %>。當于dataset綁定時,DataItem其實式一個DataRowView(如果綁定的是一個數據讀取器(dataread)它就是一個IdataRecord。)因此直接轉換成DataRowView的話,將會給性能帶來很大提升。.

<%# ctype(Container.DataItem,DataRowView).Row("字段名") %>

對數據的綁定建議使用<%# ctype(Container.DataItem,DataRowView).Row("字段名") %>。數據量大的時候可提高幾百倍的速度。使用時注意2方面:1.需在頁面添加<%@ Import namespace="System.Data"%>.2.注意字段名的大小寫(要特別注意)。如果和查詢的不一致,在某些情況下會導致比<%# DataBinder.Eval(Container.DataItem, "字段名") %>還要慢。如果想進一步提高速度,可采用<%# ctype(Container.DataItem,DataRowView).Row(0) %>的方法。不過其可讀性不高。

以上的是vb.net的寫法。在c#中:

<@% ((DataRowView)Container.DataItem)["字段名"] %>

一、 應用Ado.net的一些思考原則

  1. 選擇適當的事務類型

  2. 使用存儲過程

  3. 根據數據使用的方式來設計數據訪問層

  4. 必要時申請,盡早釋放

  5. 緩存數據,避免不必要的操作

  6. 使用服務帳戶進行連接

  7. 減少往返

  8. 僅返回需要的數據

  9. 關閉可關閉的資源

二、 Connection

數據庫連接是一種共享資源,并且打開和關閉的開銷較大。Ado.net默認啟用了連接池機制,關閉連接不會真的關閉物理連接,而只是把連接放回到連接池中。因為池中共享的連接資源始終是有限的,如果在使用連接后不盡快關閉連接,

那么就有可能導致申請連接的線程被阻塞住,影響整個系統的性能表現。

1、在方法中打開和關閉連接

這個原則有幾層含義:

1)主要目的是為了做到必要時申請和盡早釋放

2)不要在類的構造函數中打開連接、在析構函數中釋放連接。因為這將依賴于垃圾回收,而垃圾回收只受內存影響,

回收時機不定

3)不要在方法之間傳遞連接,這往往導致連接保持打開的時間過長

這里強調一下在方法之間傳遞連接的危害:曾經在壓力測試中遇到過一個測試案例,當增大用戶數的時候,這個案例要比別

的案例早很久就用掉連接池中的所有連接。經分析,就是因為A方法把一個打開的連接傳遞到了B方法,而B方法又調用了一個

自行打開和關閉連接的C方法。在A方法的整個運行期間,它至少需要占用兩條連接才能夠成功工作,并且其中的一條連接占用時間還特別長,所以造成連接池資源緊張,影響了整個系統的可伸縮性!

2、顯式關閉連接

Connection對象本身在垃圾回收時可以被關閉,而依賴垃圾回收是很不好的策略。推薦使用using語句顯式關閉連接,如下例:

using (SqlConnection conn =new SqlConnection(connString)) { conn.Open(); } // Dispose is automatically called on the conn variable here

3、確保連接池啟用

Ado.net是為每個不同的連接串建立連接池,因此應該確保連接串不會出現與具體用戶相關的信息。另外,要注意連接串是

大小寫敏感的。

4、不要緩存連接

例如,把連接緩存到Session或Application中。在啟用連接池的情況下,這種做法沒有任何意義。

三、Command

1、 使用ExecuteScalar和ExecuteNonQuery

如果想返回像Count(*)、Sum(Price)或Avg(Quantity)那樣的單值,可以使用ExecuteScalar方法。ExecuteScalar返回第一行第一列的值,將結果集作為標量值返回。因為單獨一步就能完成,所以ExecuteScalar不僅簡化了代碼,還提高了性能。

使用不返回行的SQL語句時,例如修改數據(INSERT、UPDATE或DELETE)或僅返回輸出參數或返回值,請使用ExecuteNonQuery。這避免了用于創建空DataReader的任何不必要處理。

2、使用Prepare

當需要重復執行同一SQL語句多次,可考慮使用Prepare方法提升效率。需要注意的是,如果只是執行一次或兩次,則完全沒有必要。例如:

cmd.CommandText ="insert into Table1 ( Col1, Col2 ) values ( @val1, @val2 )"; cmd.Parameters.Add( "@val1", SqlDbType.Int, 4, "Col1" ); cms.Parameters.Add( "@val2", SqlDbType.NChar, 50, "Col2"); cmd.Parameters[0].Value =1; cmd.Parameters[1].Value ="XXX"; cmd.Prepare(); cmd.ExecuteNonQuery(); cmd.Parameters[0].Value =2; cmd.Parameters[1].Value ="YYY"; cmd.ExecuteNonQuery(); cmd.Parameters[0].Value =3; cmd.Parameters[1].Value ="ZZZ"; cmd.ExecuteNonQuery();

3、使用綁定變量

SQL語句需要先被編譯成執行計劃,然后再執行。如果使用綁定變量的方式,那么這個執行計劃就可以被后續執行的SQL語句所復用。而如果直接把參數合并到了SQL語句中,由于參數值千變萬化,執行計劃就難以被復用了。例如上面Prepare一節給出的示例,如果把參數值直接寫到insert語句中,那么上面的四次調用將需要編譯四次執行計劃。

為避免這種情況造成性能損失,要求一律使用綁定變量方式。

四、 DataReader

DataReader最適合于訪問只讀的單向數據集。與DataSet不同,數據集并不全部在內存中,而是隨不斷發出的read請求,一旦發現數據緩沖區中的數據均被讀取,則從數據源傳輸一個數據緩沖區大小的數據塊過來。另外,DataReader保持連接,DataSet則與連接斷開。

1、 顯式關閉DataReader

與連接類似,也需要顯式關閉DataReader。另外,如果與DataReader關聯的Connection僅為DataReader服務的話,可考慮使用Command對象的ExecuteReader(CommandBehavior.CloseConnection)方式。這可以保證當DataReader關閉時,同時自動關閉Connection。

2、用索引號訪問代替名稱索引號訪問屬性

從Row中訪問某列屬性,使用索引號的方式比使用名稱方式有細微提高。如果會被頻繁調用,例如在循環中,那么可考慮此類優化。示例如下:

cmd.CommandText ="select Col1, Col2 from Table1" ; SqlDataReader dr = cmd.ExecuteReader(); int col1 = dr.GetOrdinal("Col1"); int col2 = dr.GetOrdinal("Col2"); while (dr.Read()) { Console.WriteLine( dr[col1] +"_"+ dr[col2]); }

3、使用類型化方法訪問屬性

從Row中訪問某列屬性,用GetString、GetInt32這種顯式指明類型的方法,其效率較通用的GetValue方法有細微提高,因為不需要做類型轉換。

4、使用多數據集

部分場景可以考慮一次返回多數據集來降低網絡交互次數,提升效率。示例如下:

cmd.CommandText ="StoredProcedureName"; // The stored procedure returns multiple result sets.SqlDataReader dr = cmd.ExecuteReader(); while (dr.read()) // read first result set dr.NextResult(); while (dr.read())

五、DataSet

1、 利用索引加快查找行的效率

如果需要反復查找行,建議增加索引。有兩種方式:

1)設置DataTable的PrimaryKey

適用于按PrimaryKey查找行的情況。注意此時應調用DataTable.Rows.Find方法,一般慣用的Select方法不能利用索引。

2)使用DataView

適用于按Non-PrimaryKey查找行的情況。可為DataTable創建一個DataView,并通過SortOrder參數指示建立索引。此后使用Find或FindRows查找行。

一、減少往返行程(Reduce Round Trips)

使用下面的方法可以減少Web服務器和Browser之間的往返行程:

1、為Browser啟用緩存

如果呈現的內容是靜態的或變化周期較長,應啟用Browser緩存,避免發出冗余的http請求。

2、緩沖頁面輸出

如果可能,則盡量緩沖頁面輸出,處理結束后再一次傳送到客戶端,這可以避免頻繁傳遞小塊內容所造成的多次網絡交互。由于這種方式在頁面處理結束之前客戶端無法看到頁面內容,因此如果一個頁面的尺寸較大的話,可考慮使用Response.Flush方法。該方法強制輸出迄今為止在緩沖區中的內容,你應當采用合理的算法控制調用Response.Flush方法的次數。

3、使用Server.Transfer重定向請求

使用Server.Transfer方法重定向請求優于Response.Redirect方法。原因是Response.Redirect會向Broswer回送一個響應頭,在響應頭中指出重定向的URL,之后Brower使用新的URL重新發出請求。而Server.Transfer方法直接是一個簡單的服務端調用,完全沒有這些開銷!

需要注意Server.Transfer有局限性:第一,它會跳過安全檢查;第二,只適用于在同一Web應用內的頁面間跳轉。

二、避免阻塞和長時間的作業

如果需要運行阻塞或長時間運行的操作,可以考慮使用異步調用的機制,以便Web服務器能夠繼續處理其它的請求。

1、使用異步方式調用Web服務和遠程對象

只要有可能就要避免在請求的處理過程中對Web服務和遠程對象的同步調用,因為它占用的是的ASP.NET 線程池中的工作線程,這將直接影響Web服務器響應其它請求的能力。

2、考慮給不需要返回值的Web方法或遠程對象的方法添加OneWay屬性

這種模式能讓Web Server調用之后就立即返回。可根據實際情況決定是否使用這種方法。

3、使用工作隊列

將作業提交到服務器上的工作隊列中。客戶端通過發送請求來輪詢作業的執行結果。

三、 使用緩存

緩存能在很大程度上決定ASP.NET應用的最終性能。Asp.net支持頁面輸出緩存和頁面部分緩存,并提供Cache API,供應用程序緩存自己的數據。是否使用緩存可考慮下面的要點:

1、識別創建與訪問代價較大的數據

2、評估需要緩存數據的易變性

3、評估數據的使用頻次

4、 將要緩存數據中易變數據和不變數據分離,只緩存不變數據

5、選擇合適的緩存機制(除Asp.net Cache外,Application state和Session state也可以作為緩存使用)

四、 系統資源

1、考慮實現資源池以提升性能

2、明確地調用Dispose或Close釋放系統資源

3、不要緩存或長時間占用資源池中的資源

4、盡可能晚的申請,盡可能早的釋放

五、多線程

1、避免在請求處理過程中創建線程

在執行請求的過程中創建線程是一種代價較大的操作,會嚴重影響Web Server的性能。如果后續的操作必須用線程完成,建議通過thread pool來創建/管理線程。

2、避免阻塞處理請求的線程

3、避免異步調用

這和1的情況類似。異步調用會導致創建新的線程,增加服務器的負擔。所以,如果沒有并發的作業要執行,就不要執行異步調用。

4、不要依賴線程數據槽或線程靜態變量

由于執行請求的線程是ASP.NET thread pool中的工作線程,同一個Client的兩次請求不一定由相同的線程來處理。

六、 頁面處理

1、盡量減小Page的尺寸

包括縮短控件的名稱、CSS的class的名稱、去掉無謂空行和空格、禁用不需要的ViewState

2、優化復雜和代價較大的循環

3、合理利用客戶端的計算資源,將一些操作轉移到客戶端進行

4、啟用頁面輸出的緩沖區(Buffer)

如果Buffer的機制被關閉,可以用下面的方法打開。

使用程序打開頁面輸出緩存:

Response.BufferOutput = true;<%@ Page Buffer = "true" %>

使用Web.config或Machine.config配置文件的<pages>節點:

<pages buffer="true" …>

5、利用Page.IsPostBack優化頁面輸出

6、通過分離頁面的不同的內容,來提高緩存效率和減少呈現的時間

七、 ViewState

ViewState是Asp.net為服務端控件在頁面回傳之間跟蹤狀態信息而設計的一種機制。

1、在恰當的時間點初始化控件屬性

ASP.NET的控件在執行構造函數、初始化的期間設置的屬性不會被跟蹤變化;而在初始化階段之后對屬性的修改都會被跟蹤,并最終記錄到IE頁面的__VIEWSTATE之中。所以,選擇合理的初始化控件屬性的執行點,能有效的減小頁面尺寸。

2、謹慎選擇放到ViewState中的內容

放到ViewState中的內容會被序列化/反序列化,Asp.net為String、Integer、Boolean等基本類型的序列化做了優化,如果Array、ArrayList、HashTable存儲的是基本類型效率也較高,但其它類型則需要提供類型轉換器(Type Converter),否則將使用代價昂貴的二進制序列化程序。

3、 關閉ViewState

如果不需要跟蹤頁面狀態,例如頁面不會 回傳(PostBack)、不需要處理服務端控件事件或者每次頁面刷新時都會重新計算控件內容,那么就不需要用ViewState來記錄頁面狀態了。可以對特定的WebControl設置EnableViewState屬性,也可以在頁面一級設置:

<%@ Page EnableViewState="false" %>

歡迎關注我的公眾號(同步更新文章):DoNet技術分享平臺
閱讀原文

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272766.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272766.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272766.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

jstl mysql_java – jsp jstl sql與mysql中的奇怪行為

在mysql中我有一個存儲過程,其中包含一個sql&#xff1a;select firstname as i_firstname , lastname as i_lastname from roleuserwhere user_id uid ;我使用jstl代碼來獲取值&#xff1a; –call sp_select_username(?);${rows.i_firstname} ${rows.i_lastname}但是這個代…

C# 哈希表(Hashtable)用法筆記

一、什么是Hashtable&#xff1f;Hashtable 類代表了一系列基于鍵的哈希代碼組織起來的鍵/值對。它使用鍵來訪問集合中的元素。當您使用鍵訪問元素時&#xff0c;則使用哈希表&#xff0c;而且您可以識別一個有用的鍵值。哈希表中的每一項都有一個鍵/值對。鍵用于訪問集合中的項…

轉: Div與table的區別

1&#xff1a;速度和加載方式方面的區別 div 和 table 的差異不是速度&#xff0c;而是加載方式&#xff0c;速度只能是指網絡速度&#xff0c;如果速度足夠快&#xff0c;是沒有差異的&#xff1a; div 的加載方式是即讀即加載&#xff0c;遇到 <div> 沒有遇到 </div…

你的工作是為了你自己!

1、無論為誰打工&#xff0c;要為自己學東西&#xff0c;客觀為公司創造價值。我自己當年&#xff0c;無論我在方正給國內企業工作&#xff0c;還是我在雅虎給外國人工作&#xff0c;我都跟別人最大的不一樣&#xff0c;我從來不覺得我在給他們打工&#xff0c;我真的可能是很有…

java 無法注入service_SpringBoot集成shiro,MyRealm中無法@Autowired注入Service的問題

網上說了很多諸如是Spring加載順序&#xff0c;shiroFilter在Spring自動裝配bean之前的問題&#xff0c;其實也有可能忽略如下低級錯誤。在ShiroConfiguration中要使用Bean在ApplicationContext注入MyRealm&#xff0c;不能直接new對象。道理和Controller中調用Service一樣&…

python之函數用法startswith()

# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函數用法startswith() #http://www.runoob.com/python/att-string-startswith.html#startswith() #說明&#xff1a;返回布爾值,用于檢查字符串是否是以指定子字符串開頭&#xff0c;如果是則返回 True&#xff0c;否則…

別去取悅,心里沒你的人

鞋子不合適不必硬塞&#xff0c;否則磨了自己的腳&#xff1b;不必討好心里沒你的人&#xff0c;不在乎你的人&#xff0c;你付出再多&#xff0c;也打動不了他。討好心里沒你的人&#xff0c;會讓自己很累很累&#xff1b;總是遷就他&#xff0c;總是圍著他轉&#xff0c;最后…

tensorflow java 加速_Tensorflow使用GPU加速

測試faster-rcnn時&#xff0c;cpu計算速度較慢&#xff0c;調整代碼改為gpu加速運算將 with tf.Session() as sess: 替換為1 gpu_options tf.GPUOptions(per_process_gpu_memory_fraction0.9)2 with tf.Session(configtf.ConfigProto(gpu_optionsgpu_options,log_device_plac…

Install OpenStack Kilo Dashboard wiht Nginx + uWSGI On RHEL7.1

一、安裝Horizon、Nginx、uWSGI yum install -y uwsgi-plugin-python openstack-dashboard uwsgi nginx 二、配置uWSGI cat >/etc/uwsgi.ini <<EOF [uwsgi] plugins python master true processes 10 threads 2 chmod-socket 666socket 127.0.0.1:9000 pidfile …

C#枚舉類型的筆記

一、枚舉類型的概念枚舉類型聲明為一組相關的符號常數定義了一個類型名稱。枚舉用于"多項選擇"場合&#xff0c;就是程序運行時從編譯時已經設定的固定數目的“選擇”中做出決定。枚舉類型&#xff08;也稱為枚舉&#xff09;為定義一組可以賦給變量的命名整數常量提…

java動態打印_JFreeChart學習(三)——動態打印java內存使用情況

JFreeChart動態打印java內存使用情況import java.awt.BasicStroke;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt…

WPF中StringToImage和BoolToImage簡單用法

在WPF的綁定控件操作中&#xff0c;經常會通過bool值或者某些特定的string值做出相應動作。但UI層控件的很多屬性對應的都不是Bool值或者對應的只是固定的String值。 這個時候有兩方法解決該問題。 1.是在后臺cs中做出比較判斷&#xff0c;然后根據相應結果傳達UI層做出相應動作…

【必備】jQuery性能優化的38個建議

一、注意定義jQuery變量的時候添加var關鍵字這個不僅僅是jQuery&#xff0c;所有javascript開發過程中&#xff0c;都需要注意&#xff0c;請一定不要定義成如下&#xff1a;$loading $(#loading); //這個是全局定義&#xff0c;不知道哪里位置倒霉引用了相同的變量名&#xf…

java中策略設計模式_Java中的設計模式(五):策略模式

策略設計模式是行為設計模式之一。當我們為特定任務使用多個算法時&#xff0c;使用策略模式&#xff0c;客戶端決定在運行時使用的實際實現。策略模式的最佳示例之一是Collections.sort()采用Comparator參數的方法。基于Comparator接口的不同實現&#xff0c;對象將以不同的方…

isset函數

isset (PHP 4, PHP 5) isset — 檢測變量是否設置 檢測變量是否設置&#xff0c;并且不是 NULL。 如果 var 存在并且值不是 NULL 則返回 TRUE&#xff0c;否則返回 FALSE。 $a "test"; $b "anothertest";var_dump(isset($a)); // TRUE var_dump(i…

SQLl中的left join、right join、inner join詳解

left join(左聯接) 返回包括左表中的所有記錄和右表中聯結字段相等的記錄right join(右聯接) 返回包括右表中的所有記錄和左表中聯結字段相等的記錄inner join(等值連接) 只返回兩個表中聯結字段相等的行舉例如下&#xff1a;--------------------------------------------表A記…

afudos備份bios不動_bios刷壞后的兩種解決方法

通常主板新的BIOS可以修正舊版中BIOS的一些BUG&#xff0c;糾正對某些硬件和軟件的兼容問題&#xff0c;添加新硬件的支持等等&#xff0c;所以有時我們需要刷新BIOS。但刷新主板BIOS實際上是存在一定風險的&#xff0c;雖然現在各主板廠商都推出了在Windows下刷新BIOS的軟件&a…

光學基礎知識:白光、顏色混合、RGB、色彩空間

1665年&#xff0c;牛頓(Isaac Newton)進行了太陽光實驗&#xff0c;讓太陽光通過窗板的小圓孔照射在玻璃三角棱鏡上&#xff0c;光束在棱鏡中折射后&#xff0c;擴散為一個連續的彩虹顏色帶&#xff0c;牛頓稱之為光譜&#xff0c;表示連續的可見光譜。而可見光譜只是所有電磁…

SQL Server各個版本功能比較

微軟的SQlserver主要經歷了從sql server 2000 到最新的sql server 2017&#xff0c;現把各個版本的更新特性介紹如下&#xff1a;SQL SERVER 2000日志傳送索引視圖SQL SERVER 2005數據庫鏡像&#xff08;只有 SQL Server 2005 Enterprise Edition SP1 和更高版本支持異步數據庫…

java hibernate的使用_《Hibernate快速開始 – 4 – 使用JAVA持久層 API (JPA)教程》

章節目標使用JPA EntityManagerFactory使用注解提供映射信息使用 JPA 接口本教程可在 entitymanger/ 路徑下下載4.1. persistence.xml之前的章節使用了hibernate原生的配置文件hibernate.cfg.xml。然而&#xff0c;JPA中定義了不同的的自助配置文件persistence.xml。這個啟動過…