Asp.Net網(wǎng)站優(yōu)化系列之?dāng)?shù)據(jù)庫的優(yōu)化措施與索引優(yōu)化方法
更新時間:2010年06月09日 20:18:20 作者:
索引的作用就類似于書的目錄,書的目錄會按照章節(jié)的順序排列,會指想某一張的位置。這樣如果在一本數(shù)百頁的書里面查找某個章節(jié)位置的時候,我們就可以只掃描書的目錄,掃描的范圍縮小了n倍,查詢的效率自然就提高了。
另外在sql server內(nèi)存夠用的情況下索引會被放到內(nèi)存中,在內(nèi)存中查找自然又會提高效率;所以我們必須得合理利用索引。
1)對什么列建索引
數(shù)據(jù)庫默認(rèn)情況下會對主鍵建聚集索引,除了這個索引之外還需要在哪些列上建索引呢?這個問題只能具體情況具體分析,要看需要優(yōu)化的sql語句(通常是查詢次數(shù)多,查詢相應(yīng)想要高的語句),根據(jù)什么列的條件進行查詢。
例如:在論壇的數(shù)據(jù)庫中有一張表是帖子回復(fù)表,在論壇的應(yīng)用中用到最多的就是對指定帖子的某一頁的回復(fù)進行查詢,查詢回復(fù)表的條件是主貼的id;這時候在主貼字段上建索引就勢在必然。
2)一定要在主鍵上建聚集索引嗎
通常情況下sql server會自動給主鍵加上聚集索引,但也有一些例外的情況我們需要把聚集索引建在其他列上,例如我們用到了表分區(qū),而分區(qū)的字段不是主鍵,這時候就需要將聚集索引建在分區(qū)的列上。另外如果查詢時根據(jù)主鍵查詢較少,而根據(jù)其他列的查詢較頻繁,則也可以考慮將聚集索引建在非主鍵上。單需要注意的是聚集索引的列必須是不易變的列,如果聚集索引變了一會引起聚集索引內(nèi)的記錄的搬遷,造成頁page的分離與碎片;二會引起每一個非聚 集索引被修改,以便于所有相關(guān)的非聚集索引的行的索引鍵的值被糾正。這既浪費時間和空間,也導(dǎo)致需要整理的碎片,增加了不必要的開銷(每個列重組聚集鍵)。
3)復(fù)合索引(索引有兩個以上的列)要注意列順序
索引在數(shù)據(jù)庫中是以B樹的形式存儲的。包含A,B兩個列的索引會首先根據(jù)A列建B樹,A列的葉節(jié)點上才會開始根據(jù)B列建B樹。所以包含兩個列的索引就需要根據(jù)查詢條件所在列來決定兩個列在索引中的順序。
可以用下面的sql做實驗:
USE [Test]
GO
/****** 對象: Table [dbo].[testIndexOrder] 腳本日期: 05/27/2010 09:11:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[testIndexOrder](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
[LastName] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
[Desc] [nvarchar](400) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_testIndexOrder] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** 對象: Index [IX_testIndexOrder] 腳本日期: 05/27/2010 09:11:51 ******/
CREATE NONCLUSTERED INDEX [IX_testIndexOrder] ON [dbo].[testIndexOrder]
(
[FirstName] ASC,
[LastName] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
GO
declare @i INT;
DECLARE @random varchar(36);
set @i = 0;
while @i < 100000
begin
set @random = newid();
INSERT INTO [testIndexOrder]
(FirstName,LastName,[Desc])
VALUES(
substring(@random,1,8),substring(@random,12,8),@random
);
set @i = @i + 1
end
set statistics time on
select * from [testIndexOrder] where lastname = '6F-4ECA-'
select * from [testIndexOrder] where firstname = 'CAABE009'
set statistics time off
4)索引的個數(shù)問題
索引提高查詢效率是以降低更新、插入、刪除的速度為代價的。每當(dāng)索引列發(fā)生變化時都需要對索引數(shù)據(jù)進行相應(yīng)的調(diào)整。所以一個表上不可以建太多的索引,除非你完全不在乎修改數(shù)據(jù)的效率。另外sql server本身會對索引的數(shù)量和索引的數(shù)據(jù)長度有限制,具體請參考
5)在必要時重建索引
Sql server運行一段時間之后就會形成一些索引碎片,這時候就需要重建索引了,有時候重建索引可以起到意想不到的效果。
查看索引碎片,重建索引,可以通過sql server管理器來重建;也可以通過下面的sql語句來實現(xiàn):
--顯示表testIndexOrder的索引碎片情況
DBCC SHOWCONTIG(testIndexOrder)
--重建表的索引
--第一個參數(shù),可以是表名,也可以是表ID。
--第二個參數(shù),如果是'',表示影響該表的所有索引。
--第三個參數(shù),填充因子,即索引頁的數(shù)據(jù)填充程度。如果是,表示每一個索引頁都全部填滿,此時select效率最高,但以后要插入索引時,就得移動后面的所有頁,效率很低。如果是,表示使用先前的填充因子值。
DBCC DBREINDEX(testIndexOrder,'',)
數(shù)據(jù)庫優(yōu)化是一門復(fù)雜的學(xué)問,需要不斷的學(xué)習(xí)實踐,積累經(jīng)驗。
1)對什么列建索引
數(shù)據(jù)庫默認(rèn)情況下會對主鍵建聚集索引,除了這個索引之外還需要在哪些列上建索引呢?這個問題只能具體情況具體分析,要看需要優(yōu)化的sql語句(通常是查詢次數(shù)多,查詢相應(yīng)想要高的語句),根據(jù)什么列的條件進行查詢。
例如:在論壇的數(shù)據(jù)庫中有一張表是帖子回復(fù)表,在論壇的應(yīng)用中用到最多的就是對指定帖子的某一頁的回復(fù)進行查詢,查詢回復(fù)表的條件是主貼的id;這時候在主貼字段上建索引就勢在必然。
2)一定要在主鍵上建聚集索引嗎
通常情況下sql server會自動給主鍵加上聚集索引,但也有一些例外的情況我們需要把聚集索引建在其他列上,例如我們用到了表分區(qū),而分區(qū)的字段不是主鍵,這時候就需要將聚集索引建在分區(qū)的列上。另外如果查詢時根據(jù)主鍵查詢較少,而根據(jù)其他列的查詢較頻繁,則也可以考慮將聚集索引建在非主鍵上。單需要注意的是聚集索引的列必須是不易變的列,如果聚集索引變了一會引起聚集索引內(nèi)的記錄的搬遷,造成頁page的分離與碎片;二會引起每一個非聚 集索引被修改,以便于所有相關(guān)的非聚集索引的行的索引鍵的值被糾正。這既浪費時間和空間,也導(dǎo)致需要整理的碎片,增加了不必要的開銷(每個列重組聚集鍵)。
3)復(fù)合索引(索引有兩個以上的列)要注意列順序
索引在數(shù)據(jù)庫中是以B樹的形式存儲的。包含A,B兩個列的索引會首先根據(jù)A列建B樹,A列的葉節(jié)點上才會開始根據(jù)B列建B樹。所以包含兩個列的索引就需要根據(jù)查詢條件所在列來決定兩個列在索引中的順序。
可以用下面的sql做實驗:
復(fù)制代碼 代碼如下:
USE [Test]
GO
/****** 對象: Table [dbo].[testIndexOrder] 腳本日期: 05/27/2010 09:11:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[testIndexOrder](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
[LastName] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
[Desc] [nvarchar](400) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_testIndexOrder] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** 對象: Index [IX_testIndexOrder] 腳本日期: 05/27/2010 09:11:51 ******/
CREATE NONCLUSTERED INDEX [IX_testIndexOrder] ON [dbo].[testIndexOrder]
(
[FirstName] ASC,
[LastName] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
GO
declare @i INT;
DECLARE @random varchar(36);
set @i = 0;
while @i < 100000
begin
set @random = newid();
INSERT INTO [testIndexOrder]
(FirstName,LastName,[Desc])
VALUES(
substring(@random,1,8),substring(@random,12,8),@random
);
set @i = @i + 1
end
set statistics time on
select * from [testIndexOrder] where lastname = '6F-4ECA-'
select * from [testIndexOrder] where firstname = 'CAABE009'
set statistics time off
4)索引的個數(shù)問題
索引提高查詢效率是以降低更新、插入、刪除的速度為代價的。每當(dāng)索引列發(fā)生變化時都需要對索引數(shù)據(jù)進行相應(yīng)的調(diào)整。所以一個表上不可以建太多的索引,除非你完全不在乎修改數(shù)據(jù)的效率。另外sql server本身會對索引的數(shù)量和索引的數(shù)據(jù)長度有限制,具體請參考
5)在必要時重建索引
Sql server運行一段時間之后就會形成一些索引碎片,這時候就需要重建索引了,有時候重建索引可以起到意想不到的效果。
查看索引碎片,重建索引,可以通過sql server管理器來重建;也可以通過下面的sql語句來實現(xiàn):
復(fù)制代碼 代碼如下:
--顯示表testIndexOrder的索引碎片情況
DBCC SHOWCONTIG(testIndexOrder)
--重建表的索引
--第一個參數(shù),可以是表名,也可以是表ID。
--第二個參數(shù),如果是'',表示影響該表的所有索引。
--第三個參數(shù),填充因子,即索引頁的數(shù)據(jù)填充程度。如果是,表示每一個索引頁都全部填滿,此時select效率最高,但以后要插入索引時,就得移動后面的所有頁,效率很低。如果是,表示使用先前的填充因子值。
DBCC DBREINDEX(testIndexOrder,'',)
數(shù)據(jù)庫優(yōu)化是一門復(fù)雜的學(xué)問,需要不斷的學(xué)習(xí)實踐,積累經(jīng)驗。
相關(guān)文章
在一個網(wǎng)站下再以虛擬目錄的方式掛多個網(wǎng)站的方法
在一個網(wǎng)站下再以虛擬目錄的方式掛N個網(wǎng)站的方法2010-04-04Lucene.Net實現(xiàn)搜索結(jié)果分類統(tǒng)計功能(中小型網(wǎng)站)
這篇文章主要介紹了Lucene.Net實現(xiàn)搜索結(jié)果分類統(tǒng)計功能(中小型網(wǎng)站),這種實現(xiàn)方式比較適合中小型網(wǎng)站,在數(shù)據(jù)量和搜索量不大的情況下可用。本文給大家介紹非常詳細(xì),需要的朋友可以參考下2017-03-03asp.net 通過aspnetpager為DataList分頁
今天整了半天才把DataList的分頁搞定,下面把我的設(shè)計過程給大家講講2009-12-12ASP.NET Core 實現(xiàn)基本認(rèn)證的示例代碼
這篇文章主要介紹了ASP.NET Core 實現(xiàn)基本認(rèn)證的示例代碼嗎,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10asp.net 修飾符介紹(關(guān)于public、private、protected、internal)
這篇文章主要介紹了asp.net 修飾符介紹、關(guān)于public、private、protected、internal,需要的朋友可以參考下2014-08-08.NET/ASP.NET Routing路由(深入解析路由系統(tǒng)架構(gòu)原理)
這篇文章主要介紹了.NET/ASP.NET Routing路由(深入解析路由系統(tǒng)架構(gòu)原理),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07驗證用戶必選CheckBox控件與自定義驗證javascript代碼
CheckBox控件,由于它的值是選擇與非選擇。因此在提交數(shù)據(jù)時,想讓用戶必須選擇CheckBox,普通情況之下,不好做驗證;但我們可以使用asp:CustomValidator來驗證,不過還得寫自定義驗證Javascript代碼2013-01-01