查詢操作在資料庫的操作中所佔的比重非常大,所以查詢優化技術非常重要。
要不要建索引,首先要看你的資料量如何,如果資料量不大,就沒有必要建立索引了,因為作用不大,還增加了索引的維護工作。
另外所謂根據select語句建立索引,就是對你經常查詢的列來建立索引,如果你建立了乙個索引,可是在你的select語句中很少用到這個索引,那就沒有必要了。
具體方法是看你的select語句中的where子句條件是針對哪個欄位的,就對這個字段建立索引。
1. 合理使用索引:
索引是資料庫中重要的資料結構,它的根本目的就是為了提高查詢效率。
在經常進行連線,但是沒有指定為外來鍵的列上建立索引,而不經常連線的字段則由優化器自動生成索引;
在頻繁進行排序或分組(即進行group by或order by操作)的列上建立索引;
如果待排序的列有多個,可以在這些列上建立復合索引(compound index);
在條件表示式中經常用到的不同值較多的列上建立檢索,在不同值少的列上不要建立索引。比如在雇員表的「性別」列上只有「男」與「女」兩個不同值,因此就無必要建立索引。如果建立索引不但不會提高查詢效率,反而會嚴重降低更新速度。
使用系統工具。資料庫有乙個tbcheck工具,可以在可疑的索引上進行檢查。在一些資料庫伺服器上,索引可能失效或者因為頻繁操作而使得讀取效率降低,如果乙個使用索引的查詢不明不白地慢下來,可以試著用tbcheck工具檢查索引的完整性,必要時進行修復。另外,當資料庫表更新大量資料後,刪除並重建索引可以提高查詢速度。
2.避免或簡化排序
應當簡化或避免對大型表進行重複的排序。當能夠利用索引自動以適當的次序產生輸出時,優化器就避免了排序的步驟。以下是一些影響因素:
索引中不包括乙個或幾個待排序的列;
group by或order by子句中列的次序與索引的次序不一樣;
排序的列來自不同的表。
3.消除對大型錶行資料的順序訪問
在巢狀查詢中,對錶的順序訪問對查詢效率可能產生致命的影響。比如採用順序訪問策略,乙個巢狀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
這樣就能利用索引路徑處理查詢。
4.避免相關子查詢
乙個列的標籤同時在主查詢和where子句中的查詢中出現,那麼很可能當主查詢中的列值改變之後,子查詢必須重新查詢一次。查詢巢狀層次越多,效率越低,因此應當盡量避免子查詢。如果子查詢不可避免,那麼要在子查詢中過濾掉盡可能多的行。
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.使用臨時表加速查詢
把錶的乙個子集進行排序並建立臨時表,有時能加速查詢。它有助於避免多重排序操作,而且在其他方面還能簡化優化器的工作。
sqlserver資料庫建立索引的語法:
按照索引的結構,可以將其劃分為兩大類:聚簇索引(clustered index)和非聚簇索引(noclustered index)。
按照表中建立索引的那一列(或列組合)中的資料是否各不相同,可以將索引分為唯一索引和非唯一索引。
建立索引的條件如下:
(1)只有表的擁有者才能建立索引
(2)每個表只能建立乙個聚簇索引
(3)每個表最多可以建立249個非聚簇索引
(4)索引鍵值最大為900位元組
(5)索引最多可以包含16列
(6)建立唯一性索引時,應保證建立索引的列不包括重複的資料,並且沒有兩個以上的null
(7)建立聚簇索引時,應考慮資料庫的剩餘空間。剩餘空間應為原表的120%
(8)text、ntext、image列不能建立索引
建立索引
create [unique][clustered|noclustered]
index index_name
on (column_name [asc|desc][,...n])
檢視索引資訊
sp_helpindex table_name
刪除索引
drop index tablename.indexname|viewname.indexname[,...n]
eg:if exists(select name from sysindexes where name='ix_expertise_skilllever')
droup index [expertise表名].ix_expertise_skilllever
create noclustered index ix_expertise_skilllever on exertise(skilllever) with fillfictor=30
mysql大批量資料插入優化
目前在專案中發現一張700萬的表,插入10萬條資料通過mybatis的批量插入大概需要3分鐘左右,耗時太長。現在通過mysql的load data local infile 命令進行優化插入。最後測試10萬條資料批量插入大概在3秒左右的時間。定義命令執行語句 public inte ce fastb...
mysql大批量更新資料
大批量的更新資料如果再使用傳統的 update 方法一條一條的更新,效率是很慢的,而且效能差,也很容易造成阻塞。1 使用mysql 自有的語句構建批量更新 update tble set price case id when 16 then 7.6 when 19 then 8.86 when 20...
solr大批量資料匯出
需求 有100個core,每個core4000w資料量。把所有資料匯出來。方案1.直接對每個core通過httpsolrclient先取出總條數,然後通過每次分頁讀n行,直到讀完,這個方案肯定不行,因為越到後面,讀取速度越慢,不用想都要很長時間。方案2.深度分頁 通過游標,可以使分頁速度很快。sol...