利用SQL索引提高查詢速度

2021-09-01 11:26:39 字數 3724 閱讀 8573

1.合理使用索引

索引是資料庫中重要的資料結構,它的根本目的就是為了提高查詢效率。現在大多數的資料庫產品都採用ibm最先提出的isam索引結構。

索引的使用要恰到好處,其使用原則如下:

field3上沒有索引的情況下:

對a作全表掃瞄,結果排序

對b作全表掃瞄,結果排序

結果合併。

對於很小的表或巨大的表比較合適。field3上有索引

按照表聯結的次序,b為驅動表,a為被驅動表

對b作全表掃瞄

對a作索引範圍掃瞄

如果匹配,通過a的rowid訪問

(16) 避免一對多的join。如:

select tb1.field3,tb1.field4,tb2.field2 from tb1,tb2 where tb1.field2=tb2.field2 and tb1.field2=『bu1032』 and tb2.field2= 『aaa』

不如:declare @a varchar(80)

select @a=field2 from tb2 where field2=『aaa』

select tb1.field3,tb1.field4,@a from tb1 where field2= 『aaa』

(16) 子查詢

用exists/not exists代替in/not in操作

比較:select a.field1 from a where a.field2 in(select b.field1 from b where b.field2=100)

select a.field1 from a where exists( select 1 from b where a.field2=b.field1 and b.field2=100)

select field1 from a where field1 not in( select field2 from b)

select field1 from a where not exists( select 1 from b where b.field2=a.field1)

(17) 主、外來鍵主要用於資料約束,sybase中建立主鍵時會自動建立索引,外來鍵與索引無關,提高效能必須再建索引。

(18) char型別的字段不建索引比int型別的字段不建索引更糟糕。建索引後效能只稍差一點。

(19) 使用count(*)而不要使用count(column_name),避免使用count(distinct column_name)。

(20) 等號右邊盡量不要使用欄位名,如:

select * from tb where field1 = field3

(21) 避免使用or條件,因為or不使用索引。

2.避免使用order by和group by字句。

因為使用這兩個子句會占用大量的臨時空間(tempspace),如果一定要使用,可用檢視、人工生成臨時表的方法來代替。

如果必須使用,先檢查memory、tempdb的大小。

測試證明,特別要避免乙個查詢裡既使用join又使用group by,速度會非常慢!

3.盡量少用子查詢,特別是相關子查詢。因為這樣會導致效率下降。

乙個列的標籤同時在主查詢和where子句中的查詢中出現,那麼很可能當主查詢中的列值改變之後,子查詢必須重新查詢一次。查詢巢狀層次越多,效率越低,因此應當盡量避免子查詢。如果子查詢不可避免,那麼要在子查詢中過濾掉盡可能多的行。

4.消除對大型錶行資料的順序訪問

在 巢狀查詢中,對錶的順序訪問對查詢效率可能產生致命的影響。

比如採用順序訪問策略,乙個巢狀3層的查詢,如果每層都查詢1000行,那麼這個查詢就要查詢 10億行資料。

避免這種情況的主要方法就是對連線的列進行索引。

例如,兩個表:學生表(學號、姓名、年齡……)和選課表(學號、課程號、成績)。如果兩個 表要做連線,就要在「學號」這個連線欄位上建立索引。

還可以使用並集來避免順序訪問。儘管在所有的檢查列上都有索引,但某些形式的where子句強迫優化器使用順序訪問。

下面的查詢將強迫對orders表執行順序操作:

select * from orders where (customer_num=104 and order_num>1001) or order_num=1008

雖然在customer_num和order_num上建有索引,但是在上面的語句中優化器還是使用順序訪問路徑掃瞄整個表。因為這個語句要檢索的是分離的行的集合,所以應該改為如下語句:

select * from orders where customer_num=104 and order_num>1001

union

select * from orders where order_num=1008

這樣就能利用索引路徑處理查詢。

5.避免困難的正規表示式

matches和like關鍵字支援萬用字元匹配,技術上叫正規表示式。但這種匹配特別耗費時間。例如:select * from customer where zipcode like 「98_ _ _」

即使在zipcode欄位上建立了索引,在這種情況下也還是採用順序掃瞄的方式。如果把語句改為select * from customer where zipcode >「98000」,在執行查詢時就會利用索引來查詢,顯然會大大提高速度。

另外,還要避免非開始的子串。例如語句:select * from customer where zipcode[2,3] >「80」,在where子句中採用了非開始子串,因而這個語句也不會使用索引。

6.使用臨時表加速查詢

把錶的乙個子集進行排序並建立臨時表,有時能加速查詢。它有助於避免多重排序操作,而且在其他方面還能簡化優化器的工作。例如:

select cust.name,rcvbles.balance,……other columns

from cust,rcvbles

where cust.customer_id = rcvlbes.customer_id

and rcvblls.balance>0

and cust.postcode>「98000」

order by cust.name

如果這個查詢要被執行多次而不止一次,可以把所有未付款的客戶找出來放在乙個臨時檔案中,並按客戶的名字進行排序:

select cust.name,rcvbles.balance,……other columns

from cust,rcvbles

where cust.customer_id = rcvlbes.customer_id

and rcvblls.balance>;0

order by cust.name

into temp cust_with_balance

然後以下面的方式在臨時表中查詢:

select * from cust_with_balance

where postcode>「98000」

臨時表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁碟i/o,所以查詢工作量可以得到大幅減少。

注意:臨時表建立後不會反映主表的修改。在主表中資料頻繁修改的情況下,注意不要丟失資料。

7.用排序來取代非順序訪問

非順序磁碟訪問是最慢的操作,表現在磁碟訪問臂的來回移動。sql語句隱藏了這一情況,使得我們在寫應用程式時很容易寫出要求訪問大量非順序頁的查詢。

為什麼索引可以提高查詢速度

參考 以下是關於索引的個人理解 有這麼乙個students表 我們執行一條sql語句 select from students where name 老頑童 執行結果 如果我們沒有為name欄位建立索引,這條sql語句是從頭開始一條一條比較的,比較七次 找到了老頑童所在的這一條資料。如果此時我們為n...

提高sql質量,增加查詢速度

應盡量避免在 where 子句中使用 或 操作符,否則將引擎放棄使用索引而進行全表掃瞄。對查詢進行優化,應盡量避免全表掃瞄,首先應考慮在 where 及 order by 涉及的列上建立索引。應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃瞄,如 ...

提高oracle查詢速度

參看當前排序的方式安排,如果sorts disk sorts memory 5 你就迫切需要進行排序優化了。select from v sysstat where name like sort 查詢結果 所以我們並不需要調整sort area size。因此只能通過重新索引,碎片整理來進行優化。開始...