1.Top排序問(wèn)題
我們經(jīng)常要對(duì)表某個(gè)字段進(jìn)行排序,然后取前N名。所以我們會(huì)寫如下的SQL語(yǔ)句:
select top 100 * from 表 order by Score desc
如果表非常大的話,那么這樣的操作是非常消耗資源的,因?yàn)镾QL SERVER要對(duì)整個(gè)表進(jìn)行排序,然后取前N條記錄。這樣的造作是在Temdb里邊進(jìn)行的,所以極端的時(shí)候會(huì)報(bào)Log已滿這樣的錯(cuò)誤。為了避免進(jìn)行全表的排序,我們要做的僅僅是在Score上建立索引,這樣因?yàn)镾core索引的葉級(jí)是有序的,只要在Score所以的頁(yè)級(jí)取前100個(gè),然后根據(jù)書簽查找到實(shí)際的記錄,這樣對(duì)DB的性能就會(huì)有極大的提升。
2.同一天問(wèn)題
我們經(jīng)常要查找和一個(gè)日期同一天的記錄,所以我們回寫如下的SQL語(yǔ)句:
declare @DateTime datetime
set @DateTime=getdate()
select * from 表
where convert(char(10),F_Time,120)=convert(char(10),@DateTime,120)
但是這樣寫的SQL語(yǔ)句帶來(lái)的問(wèn)題就是不能使用F_Time上的索引了。為了近可能的使用F_Time上的索引,我們可以使用時(shí)間段查詢的方式來(lái)代替上邊的語(yǔ)句。
declare @start datetime
declare @end datetime
declare @datetime datetime
set @datetime=getdate()
set @start=convert(char(10),@datetime,120) -- 一天的其始時(shí)間
set @end=dateadd(ss,-1,dateadd(d,1,@start)) -- 一天的結(jié)束時(shí)間
select *
from 表
where F_Time between @start and @end
這樣就解決了使用不上索引的問(wèn)題.
3.利用索引進(jìn)行分組操作
我們經(jīng)常要對(duì)某一字段進(jìn)行分組,而對(duì)另外一些字段進(jìn)行聚合操作。如果我們對(duì)分組的字段合理的使用索引,可以加快我們分組的速度.下邊以Northwind的Orders表為例:
-- orders表的EmployeeID上建有索引。
select EmployeeID,count(*)
from orders
group by EmployeeID
-- 查看執(zhí)行計(jì)劃,此查詢利用了EmployeeID上的索引。如改成如下查詢:
select EmployeeID,sum(Freight)
from orders
group by EmployeeID
-- 查看執(zhí)行計(jì)劃,此查詢則沒(méi)有使用EmployeeID上的索引。而是使用了全表掃描。那么原因是什么呢?是因?yàn)镕reight沒(méi)有在EmployeeID的索引上,所以通過(guò)索引不能得到結(jié)果。而如果通過(guò)書簽查詢的成本太高,所以SQL SERVER選擇了使用全表掃描。而如果我們執(zhí)行在EmployeeID和Freight上建立復(fù)合索引呢?
create index idx_EmployeeID on Orders(EmployeeID,Freight)
-- 再次執(zhí)行第二個(gè)查詢。查看執(zhí)行計(jì)劃。SQL SERVER使用的我們建立的索引。只需要使用索引就可以查詢到結(jié)果,極大的提高了我們的查詢速度。
更多軟考資料請(qǐng)?jiān)L問(wèn):考試吧軟件水平考試欄目
希望與更多網(wǎng)友交流,請(qǐng)進(jìn)入考試吧軟件水平考試論壇
北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |