咱們作開發的人員,雖然說本身不是專業從事數據庫方面研究的(如DBA),但不少時候,公司沒有專門的DBA,因此拿到具體的項目中,總體的數據庫設計都是開發人員本身寫的,隨着時間的推移,加上開發經驗的增加,愈來愈關心如何設計好的數據庫,如何寫出高效的sql語句。之因此很是關心數據庫及sql語句的寫法,主要是在程序邏輯代碼上你們都有可能寫出同樣的效率的功能方法來,而sql語句呢,對於一樣的結果集,一個初級的開發人員與一個資深的開發人員或者DBA寫出的sql語句執行效率有着很大的差距。這裏對數據庫設計略過,主要說說正確創建索引,帶來的性能提升。(還好,咱們公司有DBA,本身寫好的sql語句可讓他幫忙看看)sql
看sql 的性能,主要看執行計劃,還有cpu成本,io成本等。這裏就以一個簡的表爲例。數據庫
首先,建立一個簡單的表,通常會先建個主鍵,系統自動以主鍵建彙集索引。語句以下:數據庫設計
Code 1CREATE TABLE [dbo].[Article]( 2 [Id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL, 3 [MsId] [int] NOT NULL, 4 [Title] [nvarchar](96) NOT NULL, 5 [TitleBak] [nvarchar](96) NOT NULL, 6 [Summary] [nvarchar](512) NOT NULL, 7 [SummaryImageUrl] [nvarchar](256) NOT NULL, 8 [Tag] [nvarchar](50) NOT NULL, 9 [ArticleChannel_Id] [int] NOT NULL, 10 [ArticleCategory_Id] [int] NOT NULL, 11 [IsApproved] [bit] NOT NULL, 12 [Creator_Id] [int] NOT NULL, 13 [CreatedDateTime] [datetime] NOT NULL, 14 [ModifiedDateTime] [datetime] NOT NULL, 15 [ViewCount] [int] NOT NULL, 16 [ReplyCount] [int] NOT NULL, 17 [DiggCount] [int] NOT NULL, 18 [FavoriteCount] [int] NOT NULL, 19 [LastReplyUser_Id] [int] NOT NULL, 20 [LastReplyDateTime] [datetime] NOT NULL, 21 [RightType] [int] NOT NULL, 22 [IsDisplayContent] [bit] NOT NULL, 23 [IsSensitive] [bit] NOT NULL, 24 [Source] [int] NOT NULL, 25 CONSTRAINT [PK_Articles] PRIMARY KEY CLUSTERED 26( 27 [Id] ASC 28)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 29) ON [PRIMARY] 30
填充200000測試數據,post
Code 1DECLARE @number INT 2SET @number = 200000 3 4WHILE @number > 0 5BEGIN 6 INSERT dbo.Article 7 ( 8 MsId, 9 Title, 10 TitleBak, 11 Summary, 12 SummaryImageUrl, 13 14 Tag, 15 ArticleChannel_Id, 16 ArticleCategory_Id, 17 IsApproved, 18 Creator_Id, 19 20 CreatedDateTime, 21 ModifiedDateTime, 22 ViewCount, 23 ReplyCount, 24 DiggCount, 25 26 FavoriteCount, 27 LastReplyUser_Id, 28 LastReplyDateTime, 29 RightType, 30 IsDisplayContent, 31 32 IsSensitive, 33 Source 34 ) 35 VALUES 36 ( 37 @number, 38 'Title'+cast(@number AS VARCHAR(20)), 39 'TitleBak'+cast(@number AS VARCHAR(20)), 40 'Summary'+cast(@number AS VARCHAR(20)), 41 'SummaryImageUrl'+cast(@number AS VARCHAR(20)), 42 43 'Tag'+cast(@number AS VARCHAR(20)), 44 1, 45 2, 46 0, 47 @number, 48 49 GETDATE(), 50 GETDATE(), 51 100, 52 29, 53 123, 54 55 12, 56 @number, 57 GETDATE(), 58 1, 59 0, 60 61 0, 62 2 63 64 ) 65 SET @number=@number-1 66END 67
建立索引,何時建立,爲哪一個字段建立等等一系列的問題在這裏通通的撂下,在這裏進行一步步的帶有試探的建立非彙集索引,看看創建索引先後以及不一樣的索引會有什麼樣的不一樣。性能
先說明一下,經過執行計劃,判斷是否須要優化sql的一個簡單規則是:看執行計劃中的操做是seek(搜索)仍是scan(掃描)測試
長話短說,立刻開始,優化
WITH TEMP AS ( SELECT ROW_NUMBER() OVER (ORDER BY CreatedDateTime) AS ROW,CreatedDateTime,ViewCount FROM Article WHERE Creator_Id=199996 ) SELECT * FROM TEMP WHERE ROW BETWEEN 1 AND 5
經過執行計劃,看到是操做是彙集索引掃描。咱們剛纔說了,seek操做性能更好一些,那如何優化這條語句呢,對Creator_Id建非彙集索引。spa
建立Ix_article_creatorid 索引,設計
CREATE INDEX Ix_article_creatorid ON Article(Creator_Id)code
再看下執行計劃,
哦,加了Ix_article_creatorid索引後,彙集索引掃描操做改成索引查找和彙集索引查找,對於咱們開發人員來講,通常的認爲能夠了。若是所開發的系統在正常運行一段時間後,須要優化,能夠對此語句繼續進行優化。
看完執行計劃,想到了應該再看看cpu佔用時間,IO資源等狀況,主要用到命令
set statistics io 和 set statistics,這是性能調優時查看相關cpu佔用時間,IO資源數據的兩個比較重要的命令。
今天就先到了,下篇再介紹這兩個命令吧。
備註:
其實沒有詳細介紹如何建立高效性能的索引,主要緣由是根據不一樣的環境對待系統的要求不一樣,而優化也有所不一樣,當一個系統查詢比較頻繁,而新建,修改等操做比較少時,能夠建立覆蓋索引,將查詢字段和where子句裏的字段所有包含在內,這樣查詢的速度會比之前快不少,同時也帶來弊端,就是新建或修改等操做時,比沒有索引或沒有創建覆蓋索引時的要慢。總結一句話就是,具體問題具體分析。
數據庫裏的知識也是博大精深,並非當初認爲會寫幾條sq l語句就覺得很是精通了數據庫什麼的,真正要寫出好的語句,得下功夫,瞭解數據庫的底層,再常常問問DB牛人,慢慢積累後,也許你也能成爲DB牛人呢。總結一句話就是,只要功夫深,鐵杵磨成針。