參考:
http://blog.csdn.net/dongyuxi1987/article/details/8239739
1.數據庫索引簡介
回憶一下小時候查字典的步驟,索引和字典目錄的概念是一致的。字典目錄可以讓我們不用翻整本字典就找到我們需要的內容頁數,然后翻到那一頁就可以。索引也是一樣,索引是對記錄按照多個字段進行排序的一種展現。對表中的某個字段建立索引會創建另一種數據結構,其中保存着字段的值,每個值還包括指向與它相關記錄的指針。這樣,就不必要查詢整個數據庫,自然提升了查詢效率。同時,索引的數據結構是經過排序的,因而可以對其執行二分查找,那就更快了
2.索引的使用
很多對索引不熟悉的朋友在表中創建了索引,卻發現沒有生效,其實這大多數和我接下來講的有關。對於where子句中出現的列要想索引生效,會有一些限制,這就和前導列有關。所謂前導列,就是在創建復合索引語句的第一列或者連續的多列。
比如通過:CREATE INDEX comp_ind ON table1(x, y, z)創建索引,那么x,xy,xyz都是前導列,而yz,y,z這樣的就不是。下面講的這些,對於其他數據庫或許會有一些小的差別,這里以sqlite為標准。在where子句中,前導列必須使用等於或者in操作,最右邊的列可以使用不等式,這樣索引才可以完全生效。同時,where子句中的列不需要全建立了索引,但是必須保證建立索引的列之間沒有間隙。
用如下語句創建索引:
CREATE INDEX idx_ex1 ON ex1(a,b,c,d,e,...,y,z);
這里是一個查詢語句:
...WHERE a=5 AND b IN (1,2,3) AND c IS NULL AND d='hello'這顯然對於abcd四列都是有效的,因為只有等於和in操作,並且是前導列。
再看一個查詢語句:
... WHERE a=5 AND b IN (1,2,3) AND c>12 AND d='hello'那這里只有a,b和c的索引會是有效的,d列的索引會失效,因為它在c列的右邊,而c列使用了不等式,根據使用不等式的限制,c列已經屬於最右邊。
最后再看一條:
... WHERE b IN (1,2,3) AND c NOT NULL AND d='hello'索引將不會被使用,因為沒有使用前導列,這個查詢會是一個全表查詢。
創建如下表和索引:
db.execSQL("create table if not exists t1(a,b)");
db.execSQL("create index if not exists ia on t1(a,b)");
插入10萬條數據,分別對表進行如下操作:
select * from t1 where a='90012'
插入:insert into t1(a,b) values('10008','name1.6982235534984673')
更新:update t1 set b='name1.999999' where a = '887'
刪除:delete from t1 where a = '1010'
數據如下(5次不同的操作取平均值):
操作 無索引 有索引
查詢 170ms 5ms
插入 65ms 75ms
更新 240ms 52ms
刪除 234ms 78ms
可以看到顯著提升了查詢的速度,稍稍減慢了插入速度,還稍稍提升了更新數據和刪除數據的速度。
如果把更新和刪除中的where子句中的列換成b,速度就和沒有索引一樣了,因為索引失效。