海量資料庫的查詢優化及分頁演算法方案

2021-04-08 19:25:41 字數 4990 閱讀 9422

**如何在有著

1000

萬條資料的

ms sql server

資料庫中實現快速的資料提取和資料分頁。以下**說明了我們例項中資料庫的

「紅標頭檔案

」一表的部分資料結構:

create table [dbo].[tgongwen] (    --tgongwen

是紅標頭檔案表名

[gid] [int] identity (1, 1) not null ,

--本表的

id號,也是主鍵

[title] [varchar] (80) collate chinese_prc_ci_as null , 

--紅標頭檔案的標題

[fariqi] [datetime] null ,

--發布日期

[neibuyonghu] [varchar] (70) collate chinese_prc_ci_as null ,

--發布使用者

[reader] [varchar] (900) collate chinese_prc_ci_as null ,

--

需要瀏覽的使用者。每個使用者中間用分隔符

「,」分開

) on [primary] textimage_on [primary]

go

下面,我們來往資料庫中新增

1000

萬條資料:

declare @i int

set @i=1

while @i<=250000

begin

insert into tgongwen(fariqi,neibuyonghu,reader,title) values('2004-2-5','

通訊科','

通訊科,

辦公室,

王局長,

劉局長,

張局長,admin,

刑偵支隊

,特勤支隊

,交巡警支隊

,經偵支隊

,戶政科

,治安支隊

,外事科

','這是最先的

25萬條記錄

')

set @i=@i+1

end

go

declare @i int

set @i=1

while @i<=250000

begin

insert into tgongwen(fariqi,neibuyonghu,reader,title) values('2004-9-16','

辦公室','

辦公室,

通訊科,

王局長,

劉局長,

張局長,admin,

刑偵支隊

,特勤支隊

,交巡警支隊

,經偵支隊

,戶政科

,外事科

','這是中間的

25萬條記錄

')

set @i=@i+1

end

go

declare @h int

set @h=1

while @h<=100

begin

declare @i int

set @i=2002

while @i<=2003

begin

declare @j int

set @j=0

while @j<50

begin

declare @k int

set @k=0

while @k<50

begin

insert into tgongwen(fariqi,neibuyonghu,reader,title) values(cast(@i as varchar(4))+'-8-15 3:'+cast(@j as varchar(2))+':'+cast(@j as varchar(2)),'

通訊科','

辦公室,

通訊科,

王局長,

劉局長,

張局長,admin,

刑偵支隊

,特勤支隊

,交巡警支隊

,經偵支隊

,戶政科

,外事科

','這是最後的

50萬條記錄

')

set @k=@k+1

end

set @j=@j+1

end

set @i=@i+1

end

set @h=@h+1

end

go

declare @i int

set @i=1

while @i<=9000000

begin

insert into tgongwen(fariqi,neibuyonghu,reader,title) values('2004-5-5','

通訊科','

通訊科,

辦公室,

王局長,

劉局長,

張局長,admin,

刑偵支隊

,特勤支隊

,交巡警支隊

,經偵支隊

,戶政科

,治安支隊

,外事科

','這是最後新增的

900萬條記錄

')

set @i=@i+1000000

end

go

通過以上語句,我們建立了

25萬條由於

2023年2

月5

日發布的記錄,

25萬條由辦公室於

2023年9

月6

日發布的記錄,

2002

年和2003

年各100

個2500

條相同日期、不同分秒的記錄(共

50萬條),還有由通訊科於

2023年5

月5

日發布的

900萬條記錄,合計

1000

萬條。一、因情制宜,建立「適當

」的索引 建立

「適當

」的索引是實現查詢優化的首要前提。

索引(index

)是除表之外另一重要的、使用者定義的儲存在物理介質上的資料結構。當根據索引碼的值搜尋資料時,索引提供了對資料的快速訪問。事實上,沒有索引

,資料庫也能根據

select

語句成功地檢索到結果,但隨著表變得越來越大,使用「適當

」的索引的效果就越來越明顯。注意,在這句話中,我們用了「適當

」這個詞,這是因為,如果使用索引時不認真考慮其實現過程,索引既可以提高也會破壞資料庫的工作效能。

(一)深入淺出理解索引結構

實際上,您可以把索引理解為一種特殊的目錄。微軟的

sql server

提供了兩種索引:聚集索引(

clustered index

,也稱聚類索引、簇集索引)和非聚集索引(

nonclustered index

,也稱非聚類索引、非簇集索引)。下面,我們舉例來說明一下聚集索引和非聚集索引的區別:

其實,我們的漢語字典的正文本身就是乙個聚集索引。比如,我們要查「安

」字,就會很自然地翻開字典的前幾頁,因為「安

」的拼音是

「an」

,而按照拼音排序漢字的字典是以英文本母

「a」開頭並以

「z」結尾的,那麼「安

」字就自然地排在字典的前部。如果您翻完了所有以

「a」開頭的部分仍然找不到這個字,那麼就說明您的字典中沒有這個字;同樣的,如果查「張

」字,那您也會將您的字典翻到最後部分,因為「張

」的拼音是

「zhang」

。也就是說,字典的正文部分本身就是乙個目錄,您不需要再去查其他目錄來找到您需要找的內容。

我們把這種正文內容本身就是一種按照一定規則排列的目錄稱為

「聚集索引」。

如果您認識某個字,您可以快速地從自動中查到這個字。但您也可能會遇到您不認識的字,不知道它的發音,這時候,您就不能按照剛才的方法找到您要查的字,而需要去根據

「偏旁部首

」查到您要找的字,然後根據這個字後的頁碼直接翻到某頁來找到您要找的字。但您結合

「部首目錄」和

「檢字表

」而查到的字的排序並不是真正的正文的排序方法,比如您查「張

」字,我們可以看到在查部首之後的檢字表中「張

」的頁碼是

672頁,檢字表中「張

」的上面是「馳

」字,但頁碼卻是

63頁,「張

」的下面是「弩

」字,頁面是

390頁。很顯然,這些字並不是真正的分別位於「張

」字的上下方,現在您看到的連續的

「馳、張、弩

」三字實際上就是他們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的對映。我們可以通過這種方式來找到您所需要的字,但它需要兩個過程,先找到目錄中的結果,然後再翻到您所需要的頁碼。

我們把這種目錄純粹是目錄,正文純粹是正文的排序方式稱為

「非聚集索引」。

通過以上例子,我們可以理解到什麼是

「聚集索引」和

「非聚集索引」。

進一步引申一下,我們可以很容易的理解:每個表只能有乙個聚集索引,因為目錄只能按照一種方法進行排序。

(二)何時使用聚集索引或非聚集索引

下面的表總結了何時使用聚集索引或非聚集索引(很重要)。

動作描述

使用聚集索引

使用非聚集索引

列經常被分組排序應應

返回某範圍內的資料應不應

乙個或極少不同值

不應不應

小數目的不同值應不應

大數目的不同值不應應

頻繁更新的列不應應

外來鍵列應

應主鍵列應應

頻繁修改索引列不應應

事實上,我們可以通過前面聚集索引和非聚集索引的定義的例子來理解上表。如:返回某範圍內的資料一項。比如您的某個表有乙個時間列,恰好您把聚合索引建立在了該列,這時您查詢

2023年1

海量資料庫的查詢優化及分頁演算法方案

create procedure pagination3 tblname varchar 255 表名 strgetfields varchar 1000 需要返回的列 fldname varchar 255 排序的欄位名 pagesize int 10,頁尺寸 pageindex int 1,頁碼...

資料庫 分頁查詢優化

select top10 from admin where adminid notin select top1500000 adminid from admin 使用not in會引發全表掃瞄 理論上會,由於資料庫會對查詢進行優化,所以實際我並不知道會不會 其用時如下 cpu 時間 562 毫秒,占...

mysql資料庫分頁查詢優化

原博 mysql單錶百萬資料記錄分頁效能優化 limit優化 當資料很多需要進行分頁查詢時 需要先查出第一條資料的id然後根據id查詢大於id的資料 limt 一頁的資料量 1.直接用limit start,count分頁語句,也是我程式中用的方法 select from product limit...