sqlite效能優化1

2022-08-19 14:42:19 字數 4742 閱讀 3984

建立索引的基本語法如下:

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標記的含義 正常情況下,當提交乙個從資料庫中刪除資...