<ruby id="h6500"><table id="h6500"></table></ruby>
    1. <ruby id="h6500"><video id="h6500"></video></ruby>
          1. <progress id="h6500"><u id="h6500"><form id="h6500"></form></u></progress>
            • 軟件測試技術(shù)
            • 軟件測試博客
            • 軟件測試視頻
            • 開(kāi)源軟件測試技術(shù)
            • 軟件測試論壇
            • 軟件測試沙龍
            • 軟件測試資料下載
            • 軟件測試雜志
            • 軟件測試人才招聘
              暫時(shí)沒(méi)有公告

            字號: | 推薦給好友 上一篇 | 下一篇

            寫(xiě)出高性能SQL語(yǔ)句的十三條法則

            發(fā)布: 2011-2-21 10:03 | 作者: 不祥 | 來(lái)源: 領(lǐng)測軟件測試網(wǎng)采編 | 查看: 132次 | 進(jìn)入軟件測試論壇討論

            領(lǐng)測軟件測試網(wǎng)

              8、一些SQL查詢(xún)語(yǔ)句應加上nolock

              在SQL語(yǔ)句中加nolock是提高SQL Server并發(fā)性能的重要手段,在oracle中并不需要這樣做,因為oracle的結構更為合理,有undo表空間保存“數據前影”,該數據如果在修改中還未commit,那么你讀到的是它修改之前的副本,該副本放在undo表空間中。這樣,oracle的讀、寫(xiě)可以做到互不影響,這也是oracle廣受稱(chēng)贊的地方。SQL Server 的讀、寫(xiě)是會(huì )相互阻塞的,為了提高并發(fā)性能,對于一些查詢(xún),可以加上nolock,這樣讀的時(shí)候可以允許寫(xiě),但缺點(diǎn)是可能讀到未提交的臟數據。使用nolock有3條原則。

              (1)查詢(xún)的結果用于“插、刪、改”的不能加nolock !

              (2)查詢(xún)的表屬于頻繁發(fā)生頁(yè)分裂的,慎用nolock !

              (3)使用臨時(shí)表一樣可以保存“數據前影”,起到類(lèi)似oracle的undo表空間的功能,

              能采用臨時(shí)表提高并發(fā)性能的,不要用nolock 。

              9、聚集索引沒(méi)有建在表的順序字段上,該表容易發(fā)生頁(yè)分裂

              比如訂單表,有訂單編號orderid,也有客戶(hù)編號contactid,那么聚集索引應該加在哪個(gè)字段上呢?對于該表,訂單編號是順序添加的,如果在orderid上加聚集索引,新增的行都是添加在末尾,這樣不容易經(jīng)常產(chǎn)生頁(yè)分裂。然而,由于大多數查詢(xún)都是根據客戶(hù)編號來(lái)查的,因此,將聚集索引加在contactid上才有意義。而contactid對于訂單表而言,并非順序字段。

              比如“張三”的“contactid”是001,那么“張三”的訂單信息必須都放在這張表的第一個(gè)數據頁(yè)上,如果今天“張三”新下了一個(gè)訂單,那該訂單信息不能放在表的最后一頁(yè),而是第一頁(yè)!如果第一頁(yè)放滿(mǎn)了呢?很抱歉,該表所有數據都要往后移動(dòng)為這條記錄騰地方。

              SQL Server的索引和Oracle的索引是不同的,SQL Server的聚集索引實(shí)際上是對表按照聚集索引字段的順序進(jìn)行了排序,相當于oracle的索引組織表。SQL Server的聚集索引就是表本身的一種組織形式,所以它的效率是非常高的。也正因為此,插入一條記錄,它的位置不是隨便放的,而是要按照順序放在該放的數據頁(yè),如果那個(gè)數據頁(yè)沒(méi)有空間了,就引起了頁(yè)分裂。所以很顯然,聚集索引沒(méi)有建在表的順序字段上,該表容易發(fā)生頁(yè)分裂。

              曾經(jīng)碰到過(guò)一個(gè)情況,一位哥們的某張表重建索引后,插入的效率大幅下降了。估計情況大概是這樣的。該表的聚集索引可能沒(méi)有建在表的順序字段上,該表經(jīng)常被歸檔,所以該表的數據是以一種稀疏狀態(tài)存在的。比如張三下過(guò)20張訂單,而最近3個(gè)月的訂單只有5張,歸檔策略是保留3個(gè)月數據,那么張三過(guò)去的15張訂單已經(jīng)被歸檔,留下15個(gè)空位,可以在insert發(fā)生時(shí)重新被利用。在這種情況下由于有空位可以利用,就不會(huì )發(fā)生頁(yè)分裂。但是查詢(xún)性能會(huì )比較低,因為查詢(xún)時(shí)必須掃描那些沒(méi)有數據的空位。

              重建聚集索引后情況改變了,因為重建聚集索引就是把表中的數據重新排列一遍,原來(lái)的空位沒(méi)有了,而頁(yè)的填充率又很高,插入數據經(jīng)常要發(fā)生頁(yè)分裂,所以性能大幅下降。

              對于聚集索引沒(méi)有建在順序字段上的表,是否要給與比較低的頁(yè)填充率?是否要避免重建聚集索引?是一個(gè)值得考慮的問(wèn)題!

              10、加nolock后查詢(xún)經(jīng)常發(fā)生頁(yè)分裂的表,容易產(chǎn)生跳讀或重復讀

              加nolock后可以在“插、刪、改”的同時(shí)進(jìn)行查詢(xún),但是由于同時(shí)發(fā)生“插、刪、改”,在某些情況下,一旦該數據頁(yè)滿(mǎn)了,那么頁(yè)分裂不可避免,而此時(shí)nolock的查詢(xún)正在發(fā)生,比如在第100頁(yè)已經(jīng)讀過(guò)的記錄,可能會(huì )因為頁(yè)分裂而分到第101頁(yè),這有可能使得nolock查詢(xún)在讀101頁(yè)時(shí)重復讀到該條數據,產(chǎn)生“重復讀”。同理,如果在100頁(yè)上的數據還沒(méi)被讀到就分到99頁(yè)去了,那nolock查詢(xún)有可能會(huì )漏過(guò)該記錄,產(chǎn)生“跳讀”。

              上面提到的哥們,在加了nolock后一些操作出現報錯,估計有可能因為nolock查詢(xún)產(chǎn)生了重復讀,2條相同的記錄去插入別的表,當然會(huì )發(fā)生主鍵沖突。

              11、使用like進(jìn)行模糊查詢(xún)時(shí)應注意

              有的時(shí)候會(huì )需要進(jìn)行一些模糊查詢(xún)比如

              select * from contact where username like ‘%yue%’

              關(guān)鍵詞%yue%,由于yue前面用到了“%”,因此該查詢(xún)必然走全表掃描,除非必要,否則不要在關(guān)鍵詞前加%,

              12、數據類(lèi)型的隱式轉換對查詢(xún)效率的影響

              sql server2000的數據庫,我們的程序在提交sql語(yǔ)句的時(shí)候,沒(méi)有使用強類(lèi)型提交這個(gè)字段的值,由sql server 2000自動(dòng)轉換數據類(lèi)型,會(huì )導致傳入的參數與主鍵字段類(lèi)型不一致,這個(gè)時(shí)候sql server 2000可能就會(huì )使用全表掃描。Sql2005上沒(méi)有發(fā)現這種問(wèn)題,但是還是應該注意一下。

              13、SQL Server 表連接的三種方式

              (1)Merge Join

              (2)Nested Loop Join

              (3)Hash Join

              SQL Server 2000只有一種join方式——Nested Loop Join,如果A結果集較小,那就默認作為外表,A中每條記錄都要去B中掃描一遍,實(shí)際掃過(guò)的行數相當于A(yíng)結果集行數x B結果集行數。所以如果兩個(gè)結果集都很大,那Join的結果很糟糕。

              SQL Server 2005新增了Merge Join,如果A表和B表的連接字段正好是聚集索引所在字段,那么表的順序已經(jīng)排好,只要兩邊拼上去就行了,這種join的開(kāi)銷(xiāo)相當于A(yíng)表的結果集行數加上B表的結果集行數,一個(gè)是加,一個(gè)是乘,可見(jiàn)merge join 的效果要比Nested Loop Join好多了。

              如果連接的字段上沒(méi)有索引,那SQL2000的效率是相當低的,而SQL2005提供了Hash join,相當于臨時(shí)給A,B表的結果集加上索引,因此SQL2005的效率比SQL2000有很大提高,我認為,這是一個(gè)重要的原因。

              總結一下,在表連接時(shí)要注意以下幾點(diǎn):

              (1)連接字段盡量選擇聚集索引所在的字段

              (2)仔細考慮where條件,盡量減小A、B表的結果集

              (3)如果很多join的連接字段都缺少索引,而你還在用SQL Server 2000,趕緊升級吧。

            延伸閱讀

            文章來(lái)源于領(lǐng)測軟件測試網(wǎng) http://kjueaiud.com/

            22/2<12

            關(guān)于領(lǐng)測軟件測試網(wǎng) | 領(lǐng)測軟件測試網(wǎng)合作伙伴 | 廣告服務(wù) | 投稿指南 | 聯(lián)系我們 | 網(wǎng)站地圖 | 友情鏈接
            版權所有(C) 2003-2010 TestAge(領(lǐng)測軟件測試網(wǎng))|領(lǐng)測國際科技(北京)有限公司|軟件測試工程師培訓網(wǎng) All Rights Reserved
            北京市海淀區中關(guān)村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
            技術(shù)支持和業(yè)務(wù)聯(lián)系:info@testage.com.cn 電話(huà):010-51297073

            軟件測試 | 領(lǐng)測國際ISTQBISTQB官網(wǎng)TMMiTMMi認證國際軟件測試工程師認證領(lǐng)測軟件測試網(wǎng)

            老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月
              <ruby id="h6500"><table id="h6500"></table></ruby>
              1. <ruby id="h6500"><video id="h6500"></video></ruby>
                    1. <progress id="h6500"><u id="h6500"><form id="h6500"></form></u></progress>