OS:這里對聚集所以和非聚集所以的概念說明就不敘述了。
身為程序猿,在平時的開發中,數據的操作是經常要做的事情,大多數公司是沒有DBA的,程序開發人員的在操作數據的時候根本不會去看SQL語句執行的效率,所以就時常的遇到大數據的情況下查詢
數據庫總會遇到各種緩慢Loading的情況。
從用戶的角度來說,我褲子都脫了,你給我看這個?
從技術的角度來說,我他么這么流弊,怎么可以讓查詢這么卡。
因此,作為程序猿的我們,在沒有DBA的情況下,要掌握最基本的加快數據庫查詢的意識和技能;
直接上實例,動態說明,有圖有真相,簡單粗暴。
這里我們先創建一張表:
CREATE TABLE [dbo].[Student](
[ID] [INT] IDENTITY(1,1) NOT NULL,
[Name] [NVARCHAR](50) NOT NULL,
[Age] [INT] NOT NULL,
[Height] [INT] NOT NULL,
[Address] [NVARCHAR](100) NULL,
[Class] [NVARCHAR](50) NOT NULL,
[EntranceDateTime] [DATETIME] NOT NULL,
CONSTRAINT [PK_Student]
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Student] ADD CONSTRAINT [DF_Student_EntranceDateTime] DEFAULT (GETDATE()) FOR [EntranceDateTime]
GO
往表里插入 500萬數據:
DECLARE @i INT;
SET @i=1;
WHILE(@i<5000001)BEGIN
INSERT INTO dbo.Student(Name,Age,Height,[Address],Class,EntranceDateTime)
VALUES('yang_'+CONVERT(NVARCHAR(10),@i),RAND()*10+7,RAND()*100+50,'廈門土豪小區1座'+CONVERT(NVARCHAR(10),CONVERT(INT,RAND()*100+1))+'號',CONVERT(NVARCHAR(10),CONVERT(INT,RAND()*6+1))+'年級',GETDATE())
SET @i=@i+1;
END
1.合理的使用索引提高查詢速度
查詢表里,所有年齡為10的名字,如圖:
從圖中可以看出,使用了聚集索引掃描,邏輯讀取55057次
添加索引:
CREATE NONCLUSTERED INDEX [IX_Student_Age_Name] ON [dbo].[Student]
(
[Age] ASC
)
INCLUDE ( [Name]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO 、
很明顯的看出來,查詢優化器使用了索引查找,邏輯讀取次數變少為:2411,很可觀。
(在執行計劃中看到索引查找,就是說明索引被使用到了,如果出現索引掃描就說明索引沒有被使用到)
這里注意:
誤區:我添加了索引查詢速度就一定比表掃描來得快,并且索引一定會被使用
我的總結理解:一,索引不一定比掃描快,在數據量少的情況下,使用表掃描會比索引來得快,二,添加了索引不一定會被使用,首先要知道sqlserver在執行語句的時候會選擇最優耗能少的方案去執行,在索引無法達到最高效的情況下,就不會被使用到。
比如:
下面的查詢操作,就沒有使用到索引了,而是使用到了聚集索引掃描
出現上面的情況是為什么呢?
因為我創建的索引里,只有覆蓋了Name字段,現在我查詢的是Address字段,不在索引的覆蓋中,那么查詢優化器在執行語句的時候就沒有使用到了索引,選擇了開銷更小的聚集索引掃描
但是我就是這么任性,要強制要求使用索引來查詢,結果如截圖:
這個結果就很明顯了,邏輯讀次數,和掃描次數多了很多。計劃里也給了提示,讓我們索引覆蓋Address字段
2.合理的使用聚集索引
我們在添加表的主鍵的時候就會默認的將主鍵添加為聚集索引,但是并不是聚集索引就一定要是主鍵字段,一張表就只能添加一個聚集索引,所以合理的利用聚集索引的特性,可以很大的提高查詢速度。
一般我們都是在自增的ID設置為主鍵,但是又很少會對ID進行查詢操作,更多的會對表中的其他字段進行查詢,比如:時間字段。
這個時候就可以將聚集索引加到時間字段里,你會發現整個查詢就會高效很多。
3,4,5,6
未完待續。。。
-----------------------------------[我只是美麗的分割線]-----------------------------------------
索引的優缺點
優點: 加快訪問速度, 加強行的唯一性
缺點: 帶索引的表在數據庫中需要更多的存儲空間,操縱數據的命令需要更長的處理時間,因為它們需要對索引進行更新
創建索引的指導原則
請按照下列標準選擇建立索引的列:
該列用于頻繁搜索
該列用于對數據進行排序
請不要使用下面的列創建索引:
列中僅包含幾個不同的值。
表中僅包含幾行。為小型表創建索引可能不太劃算,因為SQL Server在索引中搜索數據所花的時間比在表中逐行搜索所花的時間更長
假設我們在Col1列上創建了單列索引,可以在以下謂詞上進行索引查找:
Ø [Col1] = 3.14
Ø [Col1] > 100
Ø [Col1] BETWEEN 0 AND 99
Ø [Col1] LIKE 'abc%'
Ø [Col1] IN (2, 3, 5, 7)
然而,在以下謂詞上將不能使用索引查找:
Ø ABS([Col1]) = 1
Ø [Col1] + 1 = 9
Ø [Col1] LIKE '%abc'
-----------------------------------[我只是美麗的分割線]-----------------------------------------