自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android性能優(yōu)化之?dāng)?shù)據(jù)庫優(yōu)化

移動開發(fā) Android
本文為性能優(yōu)化的第一篇——數(shù)據(jù)庫性能優(yōu)化,原理適用于大部分?jǐn)?shù)據(jù)庫包括Sqlite、Mysql、Oracle、Sql server,詳細(xì)介紹了索引(優(yōu)缺點(diǎn)、分類、場景、規(guī)則)和事務(wù),最后介紹了部分單獨(dú)針對Sqlite的優(yōu)化。

1、索引
簡單的說,索引就像書本的目錄,目錄可以快速找到所在頁數(shù),數(shù)據(jù)庫中索引可以幫助快速找到數(shù)據(jù),而不用全表掃描,合適的索引可以大大提高數(shù)據(jù)庫查詢的效率。
(1). 優(yōu)點(diǎn)
大大加快了數(shù)據(jù)庫檢索的速度,包括對單表查詢、連表查詢、分組查詢、排序查詢。經(jīng)常是一到兩個數(shù)量級的性能提升,且隨著數(shù)據(jù)數(shù)量級增長。

(2). 缺點(diǎn)
索引的創(chuàng)建和維護(hù)存在消耗,索引會占用物理空間,且隨著數(shù)據(jù)量的增加而增加。
在對數(shù)據(jù)庫進(jìn)行增刪改時需要維護(hù)索引,所以會對增刪改的性能存在影響。

(3). 分類
a. 直接創(chuàng)建索引和間接創(chuàng)建索引
直接創(chuàng)建: 使用sql語句創(chuàng)建,Android中可以在SQLiteOpenHelper的onCreate或是onUpgrade中直接excuSql創(chuàng)建語句,語句如

  1. CREATE INDEX mycolumn_index ON mytable (myclumn) 

間接創(chuàng)建: 定義主鍵約束或者唯一性鍵約束,可以間接創(chuàng)建索引,主鍵默認(rèn)為唯一索引。

b. 普通索引和唯一性索引
普通索引:

  1. CREATE INDEX mycolumn_index ON mytable (myclumn) 

唯一性索引:保證在索引列中的全部數(shù)據(jù)是唯一的,對聚簇索引和非聚簇索引都可以使用,語句為

  1. CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn) 

c. 單個索引和復(fù)合索引

單個索引:索引建立語句中僅包含單個字段,如上面的普通索引和唯一性索引創(chuàng)建示例。
復(fù)合索引:又叫組合索引,在索引建立語句中同時包含多個字段,語句如:

CREATE INDEX name_index ON username(firstname, lastname)

  1. CREATE INDEX name_index ON username(firstname, lastname) 

其中firstname為前導(dǎo)列。

d. 聚簇索引和非聚簇索引(聚集索引,群集索引)
聚簇索引:物理索引,與基表的物理順序相同,數(shù)據(jù)值的順序總是按照順序排列,語句為:

  1. CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH ALLOW_DUP_ROW 

其中WITH ALLOW_DUP_ROW表示允許有重復(fù)記錄的聚簇索引

非聚簇索引:

  1. CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) 

索引默認(rèn)為非聚簇索引

(4). 使用場景
在上面講到了優(yōu)缺點(diǎn),那么肯定會對何時使用索引既有點(diǎn)明白又有點(diǎn)糊涂吧,那么下面總結(jié)下:
a.  當(dāng)某字段數(shù)據(jù)更新頻率較低,查詢頻率較高,經(jīng)常有范圍查詢(>, <, =, >=, <=)或order by、group by發(fā)生時建議使用索引。并且選擇度越大,建索引越有優(yōu)勢,這里選擇度指一個字段中唯一值的數(shù)量/總的數(shù)量。
b.  經(jīng)常同時存取多列,且每列都含有重復(fù)值可考慮建立復(fù)合索引

(5). 索引使用規(guī)則
a.  對于復(fù)合索引,把使用最頻繁的列做為前導(dǎo)列(索引中***個字段)。如果查詢時前導(dǎo)列不在查詢條件中則該復(fù)合索引不會被使用。

  1. create unique index PK_GRADE_CLASS on student (grade, class) 


 

  1. select * from student where class = 2未使用到索引 
  2. select * from dept where grade = 3使用到了索引 

b.  避免對索引列進(jìn)行計算,對where子句列的任何計算如果不能被編譯優(yōu)化,都會導(dǎo)致查詢時索引失效
 

  1. select * from student where tochar(grade)=’2′ 


c.  比較值避免使用NULL
d.  多表查詢時要注意是選擇合適的表做為內(nèi)表。連接條件要充份考慮帶有索引的表、行數(shù)多的表,內(nèi)外表的選擇可由公式:外層表中的匹配行數(shù)*內(nèi)層表中每一次查找的次數(shù)確定,乘積最小為***方案。實(shí)際多表操作在被實(shí)際執(zhí)行前,查詢優(yōu)化器會根據(jù)連接條件,列出幾組可能的連接方案并從中找出系統(tǒng)開銷最小的***方案。

e.  查詢列與索引列次序一致
f.  用多表連接代替EXISTS子句
g.  把過濾記錄數(shù)最多的條件放在最前面
h.  善于使用存儲過程,它使sql變得更加靈活和高效(Sqlite不支持存儲過程::>_<:: )

(6)索引檢驗(yàn)

建立了索引,對于某條sql語句是否使用到了索引可以通過執(zhí)行計劃查看是否用到了索引。

2、使用事務(wù)
使用事務(wù)的兩大好處是原子提交和更優(yōu)性能。
(1) 原子提交
原則提交意味著同一事務(wù)內(nèi)的所有修改要么都完成要么都不做,如果某個修改失敗,會自動回滾使得所有修改不生效。

(2) 更優(yōu)性能
Sqlite默認(rèn)會為每個插入、更新操作創(chuàng)建一個事務(wù),并且在每次插入、更新后立即提交。

這樣如果連續(xù)插入100次數(shù)據(jù)實(shí)際是創(chuàng)建事務(wù)->執(zhí)行語句->提交這個過程被重復(fù)執(zhí)行了100次。如果我們顯示的創(chuàng)建事務(wù)->執(zhí)行100條語句->提交會使得這個創(chuàng)建事務(wù)和提交這個過程只做一次,通過這種一次性事務(wù)可以使得性能大幅提升。尤其當(dāng)數(shù)據(jù)庫位于sd卡時,時間上能節(jié)省兩個數(shù)量級左右。

Sqlte顯示使用事務(wù),示例代碼如下:


  1. public void insertWithOneTransaction() { 
  2.     SQLiteDatabase db = sqliteOpenHelper.getWritableDatabase(); // Begins a transaction  db.beginTransaction(); 
  3. try { // your sqls for (int i = 0; i < 100; i++) { 
  4.             db.insert(yourTableName, null, value); 
  5.         } // marks the current transaction as successful  db.setTransactionSuccessful(); 
  6.     } catch (Exception e) { // process it  e.printStackTrace(); 
  7.     } finally { // end a transaction  db.endTransaction(); 
  8.     } 

其中sqliteOpenHelper.getWritableDatabase()表示得到寫表權(quán)限。

3、其他優(yōu)化
(1) 語句的拼接使用StringBuilder代替String
這個就不多說了,簡單的string相加會導(dǎo)致創(chuàng)建多個臨時對象消耗性能。StringBuilder的空間預(yù)分配性能好得多。如果你對字符串的長度有大致了解,如100字符左右,可以直接new StringBuilder(128)指定初始大小,減少空間不夠時的再次分配。

(2) 讀寫表

在寫表時調(diào)用sqliteOpenHelper..getWritableDatabase(),在讀表時候調(diào)用sqliteOpenHelper..getReadableDatabase(),getReadableDatabase性能更優(yōu)。

(3) 查詢時返回更少的結(jié)果集及更少的字段。
查詢時只取需要的字段和結(jié)果集,更多的結(jié)果集會消耗更多的時間及內(nèi)存,更多的字段會導(dǎo)致更多的內(nèi)存消耗。

(4) 少用cursor.getColumnIndex

根據(jù)性能調(diào)優(yōu)過程中的觀察cursor.getColumnIndex的時間消耗跟cursor.getInt相差無幾??梢栽诮ū淼臅r候用static變量記住某列的index,直接調(diào)用相應(yīng)index而不是每次查詢。


  1. public static final String       HTTP_RESPONSE_TABLE_ID = android.provider.BaseColumns._ID;
  2. public static final String       HTTP_RESPONSE_TABLE_RESPONSE = "response"public List<Object> getData() { 
  3.     …… 
  4.     cursor.getString(cursor.getColumnIndex(HTTP_RESPONSE_TABLE_RESPONSE)); 
  5.     …… 

優(yōu)化為

public static final String HTTP_RESPONSE_TABLE_ID = android.provider.BaseColumns._ID;  public static final String HTTP_RESPONSE_TABLE_RESPONSE  = "response";  public static final int HTTP_RESPONSE_TABLE_ID_INDEX  = 0;  public static final int HTTP_RESPONSE_TABLE_URL_INDEX = 1;  public List<Object> getData() {     ……     cursor.getString(HTTP_RESPONSE_TABLE_RESPONSE_INDEX);     …… }

 

4、異步線程
Sqlite是常用于嵌入式開發(fā)中的關(guān)系型數(shù)據(jù)庫,完全開源。
與Web常用的數(shù)據(jù)庫Mysql、Oracle db、sql server不同,Sqlite是一個內(nèi)嵌式的數(shù)據(jù)庫,數(shù)據(jù)庫服務(wù)器就在你的程序中,無需網(wǎng)絡(luò)配置和管理,數(shù)據(jù)庫服務(wù)器端和客戶端運(yùn)行在同一進(jìn)程內(nèi),減少了網(wǎng)絡(luò)訪問的消耗,簡化了數(shù)據(jù)庫管理。不過Sqlite在并發(fā)、數(shù)據(jù)庫大小、網(wǎng)絡(luò)方面存在局限性,并且為表級鎖,所以也沒必要多線程操作。

 

Android中數(shù)據(jù)不多時表查詢可能耗時不多,不會導(dǎo)致anr,不過大于100ms時同樣會讓用戶感覺到延時和卡頓,可以放在線程中運(yùn)行,但sqlite在并發(fā)方面存在局限,多線程控制較麻煩,這時候可使用單線程池,在任務(wù)中執(zhí)行db操作,通過handler返回結(jié)果和ui線程交互,既不會影響UI線程,同時也能防止并發(fā)帶來的異常。實(shí)例代碼如下:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); singleThreadExecutor.execute(new Runnable() {       @Override public void run() {  // db operetions, u can use handler to send message after db.insert(yourTableName, null, value);          handler.sendEmptyMessage(xx);     } });
責(zé)任編輯:張葉青 來源: 開源社區(qū)
相關(guān)推薦

2023-07-12 08:55:16

PawSQL數(shù)據(jù)庫

2018-03-30 14:30:10

數(shù)據(jù)庫SQL語句性能優(yōu)化

2018-03-30 13:59:22

數(shù)據(jù)庫SQL語句性能優(yōu)化

2011-03-31 09:19:54

數(shù)據(jù)庫優(yōu)化

2021-07-29 14:20:34

網(wǎng)絡(luò)優(yōu)化移動互聯(lián)網(wǎng)數(shù)據(jù)存儲

2021-01-31 17:50:41

數(shù)據(jù)庫查詢程序員

2019-12-13 10:25:08

Android性能優(yōu)化啟動優(yōu)化

2011-05-20 10:30:20

ORACLE數(shù)據(jù)庫性能優(yōu)化

2011-05-18 09:39:19

Oracle數(shù)據(jù)庫性能優(yōu)化

2013-02-20 14:32:37

Android開發(fā)性能

2014-07-18 09:33:53

數(shù)據(jù)庫數(shù)據(jù)庫優(yōu)化

2010-12-10 10:17:21

關(guān)系型數(shù)據(jù)庫

2010-04-09 15:08:17

Oracle 數(shù)據(jù)庫性

2010-05-10 15:50:39

Oracle數(shù)據(jù)庫性能

2015-09-10 09:24:58

2017-01-15 15:13:37

Android性能優(yōu)化優(yōu)化點(diǎn)

2010-04-27 16:41:07

Oracle性能

2023-04-03 10:25:00

數(shù)據(jù)庫性能調(diào)優(yōu)

2009-06-30 22:31:23

關(guān)鍵參數(shù)MySQL性能優(yōu)化

2010-11-15 16:13:24

Oracle數(shù)據(jù)庫性能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號