• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

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

    寫出高性能SQL語句的十三條法則

    發布: 2011-2-21 10:03 | 作者: 不祥 | 來源: 領測軟件測試網采編 | 查看: 132次 | 進入軟件測試論壇討論

    領測軟件測試網

      8、一些SQL查詢語句應加上nolock

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

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

      (2)查詢的表屬于頻繁發生頁分裂的,慎用nolock !

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

      能采用臨時表提高并發性能的,不要用nolock 。

      9、聚集索引沒有建在表的順序字段上,該表容易發生頁分裂

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

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

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

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

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

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

      10、加nolock后查詢經常發生頁分裂的表,容易產生跳讀或重復讀

      加nolock后可以在“插、刪、改”的同時進行查詢,但是由于同時發生“插、刪、改”,在某些情況下,一旦該數據頁滿了,那么頁分裂不可避免,而此時nolock的查詢正在發生,比如在第100頁已經讀過的記錄,可能會因為頁分裂而分到第101頁,這有可能使得nolock查詢在讀101頁時重復讀到該條數據,產生“重復讀”。同理,如果在100頁上的數據還沒被讀到就分到99頁去了,那nolock查詢有可能會漏過該記錄,產生“跳讀”。

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

      11、使用like進行模糊查詢時應注意

      有的時候會需要進行一些模糊查詢比如

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

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

      12、數據類型的隱式轉換對查詢效率的影響

      sql server2000的數據庫,我們的程序在提交sql語句的時候,沒有使用強類型提交這個字段的值,由sql server 2000自動轉換數據類型,會導致傳入的參數與主鍵字段類型不一致,這個時候sql server 2000可能就會使用全表掃描。Sql2005上沒有發現這種問題,但是還是應該注意一下。

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

      (1)Merge Join

      (2)Nested Loop Join

      (3)Hash Join

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

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

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

      總結一下,在表連接時要注意以下幾點:

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

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

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

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    22/2<12

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

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>