什么是SQL的查詢優化,舉例說明
1 使用SET NOCOUNT ON 選項: 缺省地,每次執行SQL語句時,一個消息會從服務端發給客戶端以顯示SQL語句影響的行數。
這些信息對客戶端來說很少有用。通過關閉這個缺省值,你能減少在服務端和客戶端的網絡流量,幫助全面提升服務器和應用程序的性能。
為了關閉存儲過程級的這個特點,在每個存儲過程的開頭 包含“SET NOCOUNT ON”語句。 2 正確使用UNION和UNION ALL: 許多人沒完全理解UNION和UNION SELECT是怎樣工作的,因此,結果浪費了大量不必要的SQLServer資源。
當使用UNION時,它相當于在結果集上執行SELECT DISTINCT。換句話說,UNION將聯合兩個相類似的記錄集,然后搜索重復的記錄并排除。
如果這是你的目的,那么使用UNION是正 確的。但如果你使用UNION聯合的兩個記錄集沒有重復記錄,那么使用UNION會浪費資源,因為它要尋找重復記錄,即使你確定它們不存在。
所以如果你知道你要聯合的記錄集里沒有重復,那么你要使用UNION ALL,而不是UNION。UNION ALL聯合記錄集,但不搜索重復記錄,這樣減少SQLServer資源的使用,從而提升性能。
3 盡量不用SELECT * : 絕大多數情況下,不要用 * 來代替查詢返回的字段列表,用 * 的好處是代碼量少、就算是表結構或視圖的列發生變化,編寫的查詢SQL語句也不用變,都返回所有的字段。但數據庫服務器在解析時,如果碰到 *,則會先分析表的結構,然后把表的所有字段名再羅列出來。
這就增加了 分析的時間。 4 慎用SELECT DISTINCT: DISTINCT子句僅在特定功能的時候使用,即從記錄集中排除重復記錄的時候。
這是因為DISTINCT子句先獲取結果集然后去重,這樣增加SQLServer有用資源的使用。當然,如果你需要去做,那就只有去做了。
當如果你知道SELECT語句將從不返回重復記錄,那么使用DISTINCT語句對SQLServer資源不必要的浪費。 5 少用游標: 任何一種游標都會降低SQLServer性能。
有些情況不能避免,大多數情況可以避免。所以如果你的應用程序目前正在使用TSQL游標,看看這些代碼是否能夠重寫以避免它們。
如果你需要一行一行的執行操作,考慮下邊這些選項中的一個或多個來代替游標的使用: 使用臨時表 使用WHILE循環 使用派生表 使用相關子查詢 使用CASE語句 使用多個查詢 上面每一個都能取代游標并且執行更快。 如果你不能避免使用游標,至少試著提高它們的速度,找出加速游標的方法。
6 選擇最有效率的表名順序: SQLSERVER的解析器按照從右到左的順序處理FROM子句中的表名,因此FROM子句中寫在最后的表(基礎表driving table)將被最先處理,在FROM子句中包含多個表的情況下,必須選擇記錄條數最少的表作為基礎表,當SQLSERVER處理多個表時,會運用排序及合并的方式連接它們。首先 ,掃描第一個表(FROM子句中最后的那個表)并對記錄進行排序;然后掃描第二個表(FROM子句中最后第二個表);最后將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合并。
例如: 表 TAB1有 16384 條記錄,表 TAB2 有5條記錄,選擇TAB2作為基礎表 (最好的方法): select count(*) from TAB1 a, TAB2 b 選擇TAB1作為基礎表 (不佳的方法): select count(*) from TAB2 a, TAB1 b 如果有3個以上的表連接查詢,那就需要選擇交叉表(intersection table)作為基礎表,交叉表是指那個被其他表所引用的表。 7 使用表的別名(Alias): 當在SQL語句中連接多個表時,請使用表的別名并把別名前綴于每個Column上,這樣可以減少解析的時間并減少那些由Column歧義引起的語法錯誤。
8 SARG你的WHERE條件: ARGE來源于"Search Argument"(搜索參數)的首字母拼成的"SARG",它是指WHERE子句里,列和常量的比較。如果WHERE子句是sargable(可SARG的),這意味著它能利用索引加速查詢的完成。
如果WHERE子句不是可SARG的,這意味著WHERE子句不能利用索引(或至少部分不能利用), 執行的是全表或索引掃描,這會引起查詢的性能下降。 在WHERE子句里不可SARG的搜索條件如"IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE"和"LIKE '%500'",通常(但不總是)會阻止查詢優化器使用索引執行搜索。
另外在列上使用包括函數的表達式、兩邊都使用相同列的表達式、或和一個列(不是常 量)比較的表達式,都是不可SARG的。 并不是每一個不可SARG的WHERE子句都注定要全表掃描。
如果WHERE子句包括兩個可SARG和一個不可SARG的子句,那么至少可SARG的子句能使用索引(如果存在的話)幫助快速訪問數據。 大多數情況下,如果表上有包括查詢里所有SELECT、JOIN、WHERE子句用到的列的覆蓋索引,那么覆蓋索引能夠代替全表掃描去返回查詢的數據,即使它有不可SARG的WHERE子句。
但記住覆蓋索引尤其自身的缺陷,如此經常產生寬索引會增加讀磁盤I/O。某些情況下,可以把不可SARG的WHER E子句重寫成可SARG的子句。
例如: WHERE SUBSTRING(firstname,1,1) = 'm' 可以寫成: WHERE firstname 。
SQL查詢語句性能優化建議
1、查列表時,盡量把要查的字段查出,select id,name from 這樣比select * from 效率高點。
2、一個頁面有很多List要查,而這些List又屬于同一個表,只是條件不同,可以用or將所有的條件放在一個語句中,查出List,再用if根據條件判斷封裝不同List,這將很多個數據庫鏈接轉化成了一個數據庫鏈接,hibernate只要創建一個sessionfactory,效率比同時查多個語句快。
3、盡量把需要的字段放在同一張表上,這和第二條類似。
如何優化SQL語句中的物理查詢
from tab1, tab2 where tab1。
id = tab2。id and tab1。
col1 = 123 and tab2。col1 = 'abc' 照你所述的執行順序,先要tab1和tab2進行笛卡爾乘積,再按照tab1。
col1 = 123 and tab2。col1 = 'abc'進行篩選。
這樣的話,效率豈不是很低,數據庫有這么愚蠢嗎? 我想很多人都會有這個疑問,包括我在最初學習的時候也提出過這樣的問題。那么,我的這篇文章就結合這個問題來討論一下SQL Server的物理查詢處理。
首先我們必須明白邏輯處理和物理處理和區別,邏輯處理是指執行一個查詢應該產生什么樣的結果,那么邏輯查詢的各個階段就是這個查詢從邏輯上執行的先后順序,依照這個先后順序就能得到正確的結果,正如我們做四則混合運算一樣,先乘除后加減才能得到正確結果。 所以說邏輯查詢只關心產生一個我們期望的、正確的結果,它并不關心產生這個結果需要多少的資源消耗。
而物理處理就是怎么得到這個結果,這個時候才會考慮性能問題。下面我們就討論下怎么執行這個物理處理的。
當一個查詢到達數據庫引擎的時候,數據庫引擎需要做的是執行這個查詢的查詢計劃,那么這個時候就存在兩種情況,一種可能是這個查詢的查詢計劃已經在緩存中,這種情況就直接執行這個查詢計劃。 另外一種情況就是在緩存中找不到該查詢的查詢計劃。
沒有怎么辦?生成一個!怎么生成? 執行計劃是在編譯階段生成的,編譯需要經過三個步驟:分析、代數化(algebrization)、查詢優化,看見沒有這里的查詢優化過程就能解決上面的朋友提出的先笛卡爾集在篩選造成性能低的問題。 下面我就對這三個步驟作一個介紹。
第一步:分析是檢查語法并把SQL批處理轉化成分析樹的過程,如select * t1 where id in(1,2,3,4,5,6,7)在被分析樹分析后就展開成了select * t1 where id=1 or id=2 or id=3 or id=4 or id=5 or id=6 or id=7 ,除此之外還有檢查語法是否正確的功能。 第二步:接下的過程是代數化(algebrization),這個階段使用SQL Server 2005的新組件algebrizer,algebrizer組件的主要功能是綁定,因此代數化過程通常稱為綁定。
這個階段是將第一步的分析樹作為輸入,生成被稱為查詢處理器樹的輸出,用于查詢優化。 其實這個階段主要做幾個事情, 一:運算符平展,簡單的講就是把二元運算符組合成N元運算符,這里必須給出一個示例才能很好的解釋這個二元轉換成N元如第一步所示in操作展開成了一連串的or運算符,而分析器認為這些or都是二元的,也就是說它認為第一個or 的左孩子是id=1,右孩子是 (id=2 or id=3 or id=4 or id=5 or id=6 or id=7 )這個表達式,而右孩子又被認為是二元的,如此一來就必須進行一個遞歸過程。
而運算符平展過程則將這種二元運算組合成n元運算符,就避免了遞歸的過程。 二:名稱解析,這個過程其實就是檢查這個查詢中出現的表或者是表的列是不是在數據庫中真實存在。
以及在該查詢過程中是不是可見的。三:類型派生,有點抽象,舉個例子就能理解了,比如union查詢吧,union左右兩邊查詢結果對應位置的數據類型應該是一致的。
四:聚合綁定和組分綁定,執行完這個步驟后查詢處理器樹便生成了。 第三步:查詢優化,這個過程由查詢優化器組件來完成的。
查詢中應該以何種順序訪問表,使用哪種方法和使用哪個索引,應該由哪個聯接算法等都是由查詢優化器組件來決定的,但是這個決定也不是隨意的,它必須滿足的前提條件是保證最后得到的結果集必須是正確的,也就是說該結果集必須遵循邏輯處理的各個階段所得到的結果集相同。 優化器會嘗試該查詢的許多變體,一查找成本最低的計劃。
如果優化器分析該查詢的元數據得知只有一個可執行的計劃,那么它就不會再嘗試尋求更好的計劃,這個步驟叫做細微計劃優化。 如果沒有找到細微計劃優化,SQL Server將執行一些簡化,簡化就是對自身語法作一些轉換,比如在聯接前計算表的where篩選器,如前一篇描述的,邏輯查詢中where篩選總是在聯接之后計算,但是先計算where篩選器在聯接同樣能得到的正確的結果,而這樣的效率往往是更高的,所以在物理處理中where往往在join前執行的,開篇提到的那個問題只是讀者未理解邏輯處理和物理處理的差別而已。
【查詢優化】怎樣用SQL語句查看查詢的性能指標
捍郵?莼撼逯卸寥〉氖?菀呈? 物理讀取:從物理磁盤中往緩沖讀取的數據頁數; 預讀:根據執行計劃從物理磁盤中往緩沖讀取的數據頁數; 其中對于首次查詢一般情況下會有一下關系:邏輯讀取=物理讀取+預讀(其中的具體聯系,由于已經在之前的博客文章中提到,就不再詳細說明(文章名為【查詢優化】MSSQL查詢執行流程)) 同理,后面的lob邏輯讀取、物理讀取、預讀概念理解差不多,只是是對相應表進行更新或插入操作時體現。 對于掃描計數,以上圖片的查詢沒有連接查詢,因此意義不大。不過,如果連接查詢來說,特別是循環查詢那種,比如說自連接,如果循環次數越多,則掃描次數也就越多,則會使得查詢的效率越低。這是掃描計數是一個比較重要的性能體現參數。 對于邏輯讀取,由于SQLSERVER中對數據進行任何操作都要把數據讀入到緩沖當中,如果邏輯讀取的頁數越多,則查詢的性能越低。為此,邏輯讀取一般都是查詢性能體現的一個重要參數。二、SET STATISTICS TIME (SQL Server解析和編譯時間) 上面顯示的信息表明,執行這次查詢使用了多少CPU運行時間和運行查詢使用了多少時間。CPU運行時間是對運行查詢所需要的CPU資源的一種相對穩定的測量方法,與CPU的忙閑程度沒有關系。但是,每次運行查詢時這一數字也會有所不同,只是變化的范圍沒有總時間變化大。總時間是對查詢執行所需要的時間(不計算阻塞或讀數據的時間),由于服務器上的負載是在不斷變化的,因此這一數據的變化范圍有時會相當地大。
總的來說,量化地來看一個查詢語句的性能可以在幾個參數進行比較:1、CPU時間。可以比較查詢的循環掃描次數和邏輯讀取的數據量;
sql語句子查詢很多 怎么優化
1.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
2.應盡量避免在 where 子句中使用!=或操作符,否則將引擎放棄使用索引而進行全表掃描。
3.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
可以在num上設置默認值0,確保表中num列沒有null值,然后這樣查詢:
select id from t where num=0
4.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or num=20
可以這樣查詢:
select id from t where num=10
union all
select id from t where num=20
5.下面的查詢也將導致全表掃描:
select id from t where name like '%abc%'
若要提高效率,可以考慮全文檢索。