建立索引的基本語法如下:
create index index_name on table_name (column_name,...)
間接索引:
定義主鍵約束或者唯一性約束,可以間接建立索引,主鍵預設為唯一約束.所 有不需要再建立索引,以免造成浪費.
注意事項:
1.建立索引會增加資料庫的大小.
2.對於insert,update,delete操作來說,使用索引會變慢,因為同時需要維護索引的變化.
3.為資料量較小的表建立索引,往往會事倍功半.
使用索引需要根據實際情況權衡利弊,對於查詢操作量級較大,查詢要求較高的推薦使用索引
使用場景
a. 當某欄位資料更新頻率較低,查詢頻率較高,經常有範圍查詢(>, <, =, >=, <=)或order by、group by發生時建議使用索引。並且選擇度越大,建索引越有優勢,這裡選擇度指乙個欄位中唯一值的數量/總的數量。
b. 經常同時訪問多列,且每列都含有重複值可考慮建立復合索引
索引使用規則
a.對於復合索引,把使用最頻繁的列做為前導列(索引中第乙個字段)。如果查詢時前導列不在查詢條件中則該復合索引不會被使用。
如create unique index pk_grade_class on student (grade, class)
select * from student where class = 2未使用到索引
select * from dept where grade = 3使用到了索引
b.避免對索引列進行計算,對where子句列的任何計算如果不能被編譯優化,都會導致查詢時索引失效
select * from student where tochar(grade)=』2′
c.比較值避免使用null
d.多表查詢時要注意是選擇合適的表做為內錶。連線條件要充份考慮帶有索引的表、行數多的表,內外表的選擇可由公式:
外層表中的匹配行數*內層表中每一次查詢的次數確定,乘積最小為最佳方案。實際多表操作在被實際執行前,查詢優化器
會根據連線條件,列出幾組可能的連線方案並從中找出系統開銷最小的最佳方案。
e. 查詢列與索引列次序一致
f. 用多表連線代替exists子句
g. 把過濾記錄數最多的條件放在最前面
索引的運用時機:
1) 操作符:=、>、<、in等
2) 操作符between、like、or不能用索引,
如between:select * from mytable where myfield between 10 and 20;
這時就應該將其轉換成:
select * from mytable where myfield >= 10 and myfield <= 20;
此時如果在myfield上有索引的話就可以用了,大大提高速度
再如like:select * from mytable where myfield like 'sql%';
此時應該將它轉換成:
select * from mytable where myfield >= 'sql' and myfield < 'sqm';
此時如果在myfield上有索引的話就可以用了,大大提高速度
再如or:select * from mytable where myfield = 'abc' or myfield = 'xyz';
此時應該將它轉換成:
select * from mytable where myfield in ('abc', 'xyz');
此時如果在myfield上有索引的話就可以用了,大大提高速度
sqlite想要執行操作,需要將程式中的sql語句編譯成對應的sqlitestatement,比如select * from record這一句,被執行100次就需要編譯100次。對於批量處理插入或者更新的操作,我們可以使用顯式編譯來做到重用sqlitestatement。
想要做到重用sqlitestatement也比較簡單,基本如下:
1.編譯sql語句獲得sqlitestatement物件,引數使用?代替
2.在迴圈中對sqlitestatement物件進行具體資料繫結,bind方法中的index 從1開始,不是0
請參考如下簡單的使用**:
private void insertwithprecompiledstatement(sqlitedatabase db)
}在android中,每次資料庫插入,更新操作都開啟了事務,確保操作的原子性.事務的實現需要借助rollback journal檔案,因此每次資料庫操作都會對檔案進行開啟讀寫關閉操作.
在批量的進行操作時,就會反覆的對檔案進行開啟讀寫關閉,降低執行的效率.此時,我們可以顯式的使用事務,將批量操作導致的檔案操作次數變為一次.
具體的實現**如下:
private void insertwithtransaction(sqlitedatabase db)
db.settransactionsuccessful();
} catch (exception e) finally
}影響查詢效能的因素:
1. 對錶中行的檢索數目,越小越好
2. 排序與否。
3. 是否要對乙個索引。
4. 查詢語句的形式
幾個查詢優化的轉換
1. 對於單個表的單個列而言,如果都有形如t.c=expr這樣的子句,並且都是用or操作符連線起來,
形如: x = expr1 or expr2 = x or x = expr3 此時由於對於or,在sqlite中不能利用索引來優化,
所以可以將它轉換成帶有in操作符的子句:
x in(expr1,expr2,expr3)這樣就可以用索引進行優化,
效果很明顯,但是如果在都沒有索引的情況下or語句執行效率會稍優於in語句的效率。
2. 如果乙個子句的操作符是between,在sqlite中同樣不能用索引進行優化,所以也要進行相應的等價轉換:
如:a between b and c可以轉換成:(a between b and c) and (a>=b) and (a<=c)。
在上面這個子句中, (a>=b) and (a<=c)將被設為dynamic且是 (a between b and c)的子句,
那麼如果between語句已經編碼,那麼子句就忽略不計,如果存在可利用的index使得子句已經滿足條件,那麼父句則被忽略。
3. 如果乙個單元的操作符是like,那麼將做下面的轉換:x like 『abc%』,轉換成:x>=『abc』 and x<『abd』。
因為在sqlite中的like是不能用索引進行優化的,所以如果存在索引的話,則轉換後和不轉換相差很遠,因為對like不起作用,
但如果不存在索引,那麼like在效率方面也還是比不上轉換後的效率的。
子查詢扁平化
例子:select a from (select x+y as a from t1 where z<100) where a>5
對這個sql語句的執行一般預設的方法就是先執行內查詢,把結果放到乙個臨時表中,再對這個表進行外部查詢,這就要對資料處理兩次,
另外這個臨時表沒有索引,所以對外部查詢就不能進行優化了,如果對上 面的sql進行處理後可以得到如下sql語句:
select x+y as a from t1 where z<100 and a>5,這個結果顯然和上面的一樣,但此時只需要對資料進行查詢一次就夠了,
另外如果在表t1上有索引的話就避免了遍歷整個表。
運用flatten方法優化sql的條件:
1.子查詢和外查詢沒有都用集函式
2.子查詢沒有用集函式或者外查詢不是個表的連線
3.子查詢不是乙個左外連線的右運算元
4.子查詢沒有用distinct或者外查詢不是個表的連線
5.子查詢沒有用distinct或者外查詢沒有用集函式
6.子查詢沒有用集函式或者外查詢沒有用關鍵字distinct
7.子查詢有乙個from語句
8.子查詢沒有用limit或者外查詢不是表的連線
9.子查詢沒有用limit或者外查詢沒有用集函式
10.子查詢沒有用集函式或者外查詢沒用limit
11.子查詢和外查詢不是同時是order by子句
12.子查詢和外查詢沒有都用limit
13.子查詢沒有用offset
14.外查詢不是乙個復合查詢的一部分或者子查詢沒有同時用關鍵字order by和limit
15.外查詢沒有用集函式子查詢不包含order by
16.復合子查詢的扁平化:子查詢不是乙個復合查詢,或者他是乙個union all復合查詢,但他是都由若干個非集函式的查詢構 成,他的父查詢不是乙個復合查詢的子查詢,也沒有用集函式或者是distinct查詢,並且在from語句中沒有其它的表或者子查詢,父查詢和子查詢可能會包含where語句,這些都會受到上面11、12、13條件的限制。
select a+1 from (
select x from tab
union all
select y from tab
union all
select abs(z*2) from tab2
) where a!=5 order by 1
轉換為:
select x+1 from tab where x+1!=5
union all
select y+1 from tab where y+1!=5
union all
select abs(z*2)+1 from tab2 where abs(z*2)+1!=5
order by 1
SQLite效能優化
最近做了乙個專案,在系統啟動時會更新幾千條資料,剛開始就使用最簡單的寫法,直接的insert,delete,導致這個更新過程進行了300多秒,後來經查得知在處理大量資料的時候新增上事務管理,會大大的提高效能,隨後就查閱資料如何來新增事務管理。這ios的sqlite和android上面的語法真是相差很...
sqlite 效能優化
比如 空間釋放 磁碟同步 cache大小等。不要開啟。前文提高了,vacuum的效率非常低!pragma auto vacuum pragma auto vacuum 0 1 查詢或設定資料庫的auto vacuum標記。正常情況下,當提交乙個從資料庫中刪除資料的事務時,資料庫檔案不改變大小。未使用...
SQLite3效能優化
sqlite3效能調整主要通過pragma指令來實現。比如調整 空間釋放 磁碟同步 cache大小等。一.空間釋放 1.如何查詢 pragma auto vacuum 含義 查詢資料庫的auto vacuum標記。2.標記含義 auto vacuum標記的含義 正常情況下,當提交乙個從資料庫中刪除資...