亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

數據庫查詢優化(轉載)

2024-07-21 02:46:21
字體:
來源:轉載
供稿:網友
數據庫查詢優化(轉載)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的WHERE子句重寫成可 SARG的子句。例如:

WHERE SUBSTRING(firstname,1,1) = 'm'

可以寫成:

WHERE firstname like 'm%'

這兩個WHERE子句有相同的結果,但第一個是不可SARG的(因為使用了函數)將運行得慢些,而第二個是可SARG的,將運行得快些。

如果你不知道特定的WHERE子句是不是可SARG的,在查詢分析器里檢查查詢執行計劃。這樣做,你能很快的知道查詢是使用了索引還是全表掃描來返回的數據。仔細分析,許多不可SARG的查詢能寫成可SARG的查詢。下面分幾點講解WHERE條件的SARG。

8.1 WHERE子句中的連接順序

SQLSERVER采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前,那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。例如:

(低效)

SELECT * FROM EMP E

WHERE SAL > 50000

AND JOB = ‘MANAGER’

AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO)

(高效)

SELECT * FROM EMP E

WHERE 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO)

AND SAL > 50000

AND JOB = ‘MANAGER’

8.2 避免困難的正規表達式:

MATCHES和LIKE關鍵字支持通配符匹配,技術上叫正規表達式。但這種匹配特別耗費時間。例如:

SELECT * FROM customer WHERE zipcode LIKE "98_ _ _"

即使在zipcode字段上建立了索引,在這種情況下也還是采用順序掃描的方式。如果把語句改為SELECT * FROM customer WHERE zipcode >="98000",在執行查詢時就會利用索引來查詢,顯然會大大提高速度。

另外,還要避免非開始的子串。例如語句:

SELECT * FROM customer WHERE zipcode[2,3] >"80"

在where子句中采用了非開始子串,因而這個語句也不會使用索引。

8.3 避免對大型表行數據的順序存?。?p style="text-indent: 21pt;">在嵌套查詢中,對表的順序存 取對查詢效率可能產生致命的影響。比如采用順序存取策略,一個嵌套3層的查詢,如果每層都查詢1000行,那么這個查詢就要查詢10億行數據。避免這種情 況的主要方法就是對連接的列進行索引。例如,兩個表:學生表(學號、姓名、年齡……)和選課表(學號、課程號、成績)。如果兩個表要做連接,就要在“學 號”這個連接字段上建立索引。

還可以使用并集來避免順序存取。盡管在所有的檢查列上都有索引,但某些形式的where子句強迫優化器使用順序存取。下面的查詢將強迫對orders表執行順序操作:

SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008

雖然在customer_num和order_num上建有索引,但是在上面的語句中優化器還是使用順序存取路徑掃描整個表。因為這個語句要檢索的是分離的行的集合,所以應該改為如下語句:

SELECT * FROM orders WHERE customer_num=104 AND order_num>1001

UNION ALL

SELECT * FROM orders WHERE order_num=1008

這樣就能利用索引路徑處理查詢。

8.4 EXISTS和IN的使用:

在 許多基于基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接。   在這種情況下,使用EXISTS(或NOT EXISTS)通常將提高查詢的效率。在子查詢中,NOT IN子句將執行一個內部的排序和合并。無論在哪種情況下,NOT IN都是最低效的,因為它對子查詢中的表執行了一個全表遍歷。為了避免使用NOT IN,我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS。

8.5 避免在索引列上使用IS NULL和IS NOT NULL:

避免在索引中使用任何可以為空的列,SQLSERVER將無法使用該索引。對于單列索引,如果列包含空值,索引中將不存在此記錄;對于復合索引,如果每個列都為空,索引中同樣不存在此記錄。如果至少有一個列不為空,則記錄存在于索引中?! ?/p>

  如果唯一性索引建立在表的A列和B列上,并且表中存在一條記錄的A,B值為(123,null),SQLSERVER將不接受下一條具有相同A,B值(123,null)的記錄插入?! ?/p>

  如果所有的索引列都為空,SQLSERVER將認為整個鍵值為空,而空不可能等 于空,因此你可以插入1000條具有相同鍵值的記錄,當然它們都是空!因為空值不存在于索引列中,所以WHERE子句中對索引列進行空值比較將使 SQLSERVER停用該索引。下面的代碼將會很低效(索引失效):

SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL

8.6 避免在索引列上使用計算:

WHERE子句中,如果索引列是函數的一部分,優化器將不使用索引而使用全表掃描?! ?例如下面的語句低效 :

SELECT …FROM DEPT WHERE SAL * 12 > 25000

而下面的語句將是高效的:

SELECT …FROM DEPT WHERE SAL > 25000/12

請務必注意,查詢中不要對索引列進行處理,如:TRIM,substring,convert等等操作。

8.7 用WHERE子句替換HAVING子句:

避免使用HAVING子句,HAVING只會在檢索出所有記錄之后才對結果集進行過濾,這個處理需要排序、統計等操作。如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷。

9 避免或簡化排序:

應當簡化或避免對大型表進行重復的排序。當能夠利用索引自動以適當的次序產生輸出時,優化器就避免了排序的步驟。以下是一些影響因素:

l 索引中不包括一個或幾個待排序的列;

l group by或order by子句中列的次序與索引的次序不一樣;

l 排序的列來自不同的表。

為了避免不必要的排序,就要正確地增建索引,合理地合并數據庫表(盡管有時可能影響表的規范化,但相對于效率的提高是值得的)。如果排序不可避免,那么應當試圖簡化它,如縮小排序的列的范圍等。

10 臨時表的使用:

臨 時表有很多特殊的用途,象用來替代游標,不過它們仍能引起性能問題,如果這個問題能消除,SQLServer將執行得更快。在永久表和臨時表的數據行相同 的條件下,使用臨時表沒有永久表快。但有時還必須得使用臨時表,如先從存儲大量數據的永久表中提取符全條件的存放到臨時表,然后在臨時表上執行操作。如果 是直接在存儲大量數據的永久表上執行操作(如:統計、循環等),其性能將大打折扣。所以,使不使用臨時表,何時使用臨時表,需要具體情況決定。

11 是否使用視圖:

視圖最大的用途是處理安全相 關的問題,而不是一些懶惰的開發人員用來存儲經常使用的查詢的方法。例如,如果你需要允許用戶訪問特定SQLServer的數據,那么你也許可以考慮為用 戶(或組)創建一個視圖,然后給用

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久久久男| 国产精品久久久精品| 国色天香2019中文字幕在线观看| 中文字幕在线看视频国产欧美在线看完整| 欧美精品一区三区| 亚洲欧洲偷拍精品| 亚洲免费视频一区二区| 97香蕉久久超级碰碰高清版| 欧美精品videos| 国产亚洲欧洲高清| 中文字幕亚洲激情| 91产国在线观看动作片喷水| 成人中文字幕在线观看| 成人亚洲欧美一区二区三区| 欧美激情精品久久久久久变态| 日本午夜人人精品| 久久成人国产精品| 亚洲成色777777女色窝| 成人福利在线视频| 美女黄色丝袜一区| 久久综合久久美利坚合众国| 日韩激情片免费| 亚洲va男人天堂| 国产中文字幕日韩| 欧美午夜片欧美片在线观看| 萌白酱国产一区二区| 欧美精品情趣视频| 国产美女久久久| 亚洲xxxx3d| 日韩av影片在线观看| 国产精品福利网站| 久热在线中文字幕色999舞| 日韩欧美在线免费观看| 日韩欧美精品免费在线| 久久综合久中文字幕青草| 国产69久久精品成人看| 伊人伊人伊人久久| 亚洲free嫩bbb| 久久伊人色综合| 中文字幕日韩av综合精品| 日韩美女免费线视频| 91美女片黄在线观看游戏| 国产aaa精品| 美女撒尿一区二区三区| 国产精品99久久久久久久久久久久| 成人在线小视频| 欧美日韩午夜视频在线观看| 亚洲最新在线视频| 91久久久久久久久久| 日韩小视频网址| 成人精品网站在线观看| 一区二区成人精品| 91av在线国产| 欧美午夜www高清视频| 91成人国产在线观看| 欧美影院成年免费版| 狠狠躁夜夜躁人人爽天天天天97| 久久亚洲精品成人| 色综合久久久久久中文网| 欧美日韩国产精品| 成人xxxxx| 国产精品成人观看视频国产奇米| 日韩精品一二三四区| 亚洲天堂日韩电影| 狠狠色狠色综合曰曰| 午夜精品久久久久久久99热| 中文字幕国产精品久久| 国产日韩一区在线| 国产精品黄视频| 一本一本久久a久久精品综合小说| 久久久中精品2020中文| 中文字幕九色91在线| 成人激情视频在线观看| 97在线视频免费| 欧美香蕉大胸在线视频观看| 日本不卡免费高清视频| 亚洲国产成人久久| 国产精品日韩在线一区| 欧美成人午夜剧场免费观看| 97精品久久久| 亚洲一区中文字幕在线观看| 亚洲精品电影网站| 欧美日韩国内自拍| 一区二区欧美久久| 国产性猛交xxxx免费看久久| 国产美女高潮久久白浆| 色樱桃影院亚洲精品影院| 欧美成人免费全部观看天天性色| 久久久欧美精品| 91在线观看免费| 欧美激情影音先锋| 色妞在线综合亚洲欧美| 亚洲国产精品成人va在线观看| 91亚洲精华国产精华| 亚洲精品国产福利| 精品av在线播放| 奇米成人av国产一区二区三区| 亚洲女同性videos| 92国产精品视频| 成人午夜一级二级三级| 91精品视频一区| 精品高清美女精品国产区| 91在线高清免费观看| 欧美日韩一区二区免费在线观看| 色悠久久久久综合先锋影音下载| 久久精品成人欧美大片| 国产成人a亚洲精品| 欧美黑人视频一区| 欧美成人精品一区二区三区| 98精品国产高清在线xxxx天堂| 国产精品福利网| 97在线精品视频| 欧美日韩亚洲系列| 欧美视频一二三| 欧美壮男野外gaytube| 欧美成人免费播放| 日韩av男人的天堂| 亚洲午夜国产成人av电影男同| 日韩一二三在线视频播| 一区二区日韩精品| 久久夜色精品国产| 国产精品欧美日韩| 97视频色精品| 九九热这里只有在线精品视| 国产精品一区二区三区免费视频| 亚洲成人激情在线| 精品亚洲aⅴ在线观看| 97精品视频在线观看| 日韩黄色高清视频| 精品视频久久久久久| 精品久久久久久久久久久久久久| 欧美日韩综合视频| 欧美一级大胆视频| 中文字幕欧美国内| 亚洲欧美日韩中文在线| 国产精品视频专区| 91免费精品视频| 欧美性生交xxxxx久久久| 91视频国产高清| 国产精品精品一区二区三区午夜版| 久久综合伊人77777尤物| 97香蕉久久夜色精品国产| 日韩午夜在线视频| 日韩高清免费观看| 欧美最猛性xxxxx(亚洲精品)| 日韩欧美在线观看视频| 欧美综合国产精品久久丁香| 一区二区三区回区在观看免费视频| 中文字幕精品www乱入免费视频| 亚洲欧美国产视频| 欧美日韩一区二区三区在线免费观看| 欧美性69xxxx肥| 日韩欧美在线视频免费观看| 久久艳片www.17c.com| 91tv亚洲精品香蕉国产一区7ujn| 欧美在线视频在线播放完整版免费观看| 国产在线拍偷自揄拍精品| 亚洲专区国产精品| 久久久久久久久久久91| 亚洲偷熟乱区亚洲香蕉av| 亚洲电影成人av99爱色| 国产精品美女av| 国产精品99久久久久久久久久久久| 午夜精品美女自拍福到在线|