A. 資料庫性能優化有哪些措施
1、調整數據結構的設計
這一部分在開發信息系統之前完成,程序員需要考慮是否使用ORACLE資料庫的分區功能,對於經常訪問的資料庫表是否需要建立索引等。
2、調整應用程序結構設計
這一部分也是在開發信息系統之前完成,程序員在這一步需要考慮應用程序使用什麼樣的體系結構,是使用傳統的Client/Server兩層體系結構,還是使用Browser/Web/Database的三層體系結構。不同的應用程序體系結構要求的資料庫資源是不同的。
3、調整資料庫sql語句
應用程序的執行最終將歸結為資料庫中的SQL語句執行,因此SQL語句的執行效率最終決定了ORACLE資料庫的性能。ORACLE公司推薦使用ORACLE語句優化器(OracleOptimizer)和行鎖管理器(row-levelmanager)來調整優化SQL語句。
4、調整伺服器內存分配
內存分配是在信息系統運行過程中優化配置的,資料庫管理員可以根據資料庫運行狀況調整資料庫系統全局區(SGA區)的數據緩沖區、日誌緩沖區和共享池的大小;還可以調整程序全局區(PGA區)的大小。需要注意的是,SGA區不是越大越好,SGA區過大會佔用操作系統使用的內存而引起虛擬內存的頁面交換,這樣反而會降低系統。
5、調整硬碟I/O
這一步是在信息系統開發之前完成的。資料庫管理員可以將組成同一個表空間的數據文件放在不同的硬碟上,做到硬碟之間I/O負載均衡。
6、調整操作系統參數
例如:運行在UNIX操作系統上的ORACLE資料庫,可以調整UNIX數據緩沖池的大小,每個進程所能使用的內存大小等參數。
實際上,上述資料庫優化措施之間是相互聯系的。ORACLE資料庫性能惡化表現基本上都是用戶響應時間比較長,需要用戶長時間的等待。但性能惡化的原因卻是多種多樣的,有時是多個因素共同造成了性能惡化的結果,這就需要資料庫管理員有比較全面的計算機知識,能夠敏感地察覺到影響資料庫性能的主要原因所在。另外,良好的資料庫管理工具對於優化資料庫性能也是很重要的。
一、ORACLE資料庫性能優化工具
常用的資料庫性能優化工具有:
ORACLE資料庫在線數據字典,ORACLE在線數據字典能夠反映出ORACLE動態運行情況,對於調整資料庫性能是很有幫助的。
操作系統工具,例如UNIX操作系統的vmstat,iostat等命令可以查看到系統系統級內存和硬碟I/O的使用情況,這些工具對於管理員弄清出系統瓶頸出現在什麼地方有時候很有用。
SQL語言跟蹤工具(SQLTRACEFACILITY),SQL語言跟蹤工具可以記錄SQL語句的執行情況,管理員可以使用虛擬表來調整實例,使用SQL語句跟蹤文件調整應用程序性能。SQL語言跟蹤工具將結果輸出成一個操作系統的文件,管理員可以使用TKPROF工具查看這些文件。
ORACLEEnterpriseManager(OEM),這是一個圖形的用戶管理界面,用戶可以使用它方便地進行資料庫管理而不必記住復雜的ORACLE資料庫管理的命令。
EXPLAINPLAN——SQL語言優化命令,使用這個命令可以幫助程序員寫出高效的SQL語言。
二、ORACLE資料庫的系統性能評估
信息系統的類型不同,需要關注的資料庫參數也是不同的。資料庫管理員需要根據自己的信息系統的類型著重考慮不同的資料庫參數。
1、在線事務處理信息系統(OLTP),這種類型的信息系統一般需要有大量的Insert、Update操作,典型的系統包括民航機票發售系統、銀行儲蓄系統等。OLTP系統需要保證資料庫的並發性、可靠性和最終用戶的速度,這類系統使用的ORACLE資料庫需要主要考慮下述參數:
資料庫回滾段是否足夠?
是否需要建立ORACLE資料庫索引、聚集、散列?
系統全局區(SGA)大小是否足夠?
SQL語句是否高效?
2、數據倉庫系統(DataWarehousing),這種信息系統的主要任務是從ORACLE的海量數據中進行查詢,得到數據之間的某些規律。資料庫管理員需要為這種類型的ORACLE資料庫著重考慮下述參數:
是否採用B*-索引或者bitmap索引?
是否採用並行SQL查詢以提高查詢效率?
是否採用PL/SQL函數編寫存儲過程?
有必要的話,需要建立並行資料庫提高資料庫的查詢效率
三、SQL語句的調整原則
SQL語言是一種靈活的語言,相同的功能可以使用不同的語句來實現,但是語句的執行效率是很不相同的。程序員可以使用EXPLAINPLAN語句來比較各種實現方案,並選出最優的實現方案。總得來講,程序員寫SQL語句需要滿足考慮如下規則:
1、盡量使用索引。試比較下面兩條SQL語句:
語句A:SELECTdname,
(SELECTdeptnoFROMemp);
語句B:SELECTdname,deptnoFROMdeptWHERENOTEXISTS
(SELECTdeptnoFROMempWHEREdept.deptno=emp.deptno);
這兩條查詢語句實現的結果是相同的,但是執行語句A的時候,ORACLE會對整個emp表進行掃描,沒有使用建立在emp表上的deptno索引,執行語句B的時候,由於在子查詢中使用了聯合查詢,ORACLE只是對emp表進行的部分數據掃描,並利用了deptno列的索引,所以語句B的效率要比語句A的效率高一些。
2、選擇聯合查詢的聯合次序。考慮下面的例子:
SELECTstuffFROMtabaa,tabbb,tabcc
WHEREa.acolbetween:alowand:ahigh
ANDb.bcolbetween:blowand:bhigh
ANDc.ccolbetween:clowand:chigh
ANDa.key1=b.key1
AMDa.key2=c.key2;
這個SQL例子中,程序員首先需要選擇要查詢的主表,因為主表要進行整個表數據的掃描,所以主表應該數據量最小,所以例子中表A的acol列的范圍應該比表B和表C相應列的范圍小。
3、在子查詢中慎重使用IN或者NOTIN語句,使用where(NOT)exists的效果要好的多。
4、慎重使用視圖的聯合查詢,尤其是比較復雜的視圖之間的聯合查詢。一般對視圖的查詢最好都分解為對數據表的直接查詢效果要好一些。
5、可以在參數文件中設置SHARED_POOL_RESERVED_SIZE參數,這個參數在SGA共享池中保留一個連續的內存空間,連續的內存空間有益於存放大的SQL程序包。
6、ORACLE公司提供的DBMS_SHARED_POOL程序可以幫助程序員將某些經常使用的存儲過程「釘」在SQL區中而不被換出內存,程序員對於經常使用並且佔用內存很多的存儲過程「釘」到內存中有利於提高最終用戶的響應時間。
四、CPU參數的調整
CPU是伺服器的一項重要資源,伺服器良好的工作狀態是在工作高峰時CPU的使用率在90%以上。如果空閑時間CPU使用率就在90%以上,說明伺服器缺乏CPU資源,如果工作高峰時CPU使用率仍然很低,說明伺服器CPU資源還比較富餘。
使用操作相同命令可以看到CPU的使用情況,一般UNIX操作系統的伺服器,可以使用sar_u命令查看CPU的使用率,NT操作系統的伺服器,可以使用NT的性能管理器來查看CPU的使用率。
資料庫管理員可以通過查看v$sysstat數據字典中「CPUusedbythissession」統計項得知ORACLE資料庫使用的CPU時間,查看「OSUserlevelCPUtime」統計項得知操作系統用戶態下的CPU時間,查看「OSSystemcallCPUtime」統計項得知操作系統系統態下的CPU時間,操作系統總的CPU時間就是用戶態和系統態時間之和,如果ORACLE資料庫使用的CPU時間占操作系統總的CPU時間90%以上,說明伺服器CPU基本上被ORACLE資料庫使用著,這是合理,反之,說明伺服器CPU被其它程序佔用過多,ORACLE資料庫無法得到更多的CPU時間。
資料庫管理員還可以通過查看v$sesstat數據字典來獲得當前連接ORACLE資料庫各個會話佔用的CPU時間,從而得知什麼會話耗用伺服器CPU比較多。
出現CPU資源不足的情況是很多的:SQL語句的重解析、低效率的SQL語句、鎖沖突都會引起CPU資源不足。
1、資料庫管理員可以執行下述語句來查看SQL語句的解析情況:
SELECT*FROMV$SYSSTATWHERENAMEIN
('parsetimecpu','parsetimeelapsed','parsecount(hard)');
這里parsetimecpu是系統服務時間,parsetimeelapsed是響應時間,用戶等待時間,waitetime=parsetimeelapsed_parsetimecpu
由此可以得到用戶SQL語句平均解析等待時間=waitetime/parsecount。這個平均等待時間應該接近於0,如果平均解析等待時間過長,資料庫管理員可以通過下述語句
SELECTSQL_TEXT,PARSE_CALLS,EXECUTIONSFROMV$SQLAREA
ORDERBYPARSE_CALLS;
來發現是什麼SQL語句解析效率比較低。程序員可以優化這些語句,或者增加ORACLE參數SESSION_CACHED_CURSORS的值。
2、資料庫管理員還可以通過下述語句:
SELECTBUFFER_GETS,EXECUTIONS,SQL_TEXTFROMV$SQLAREA;
查看低效率的SQL語句,優化這些語句也有助於提高CPU的利用率。
3、資料庫管理員可以通過v$system_event數據字典中的「latchfree」統計項查看ORACLE資料庫的沖突情況,如果沒有沖突的話,latchfree查詢出來沒有結果。如果沖突太大的話,資料庫管理員可以降低spin_count參數值,來消除高的CPU使用率。
五、內存參數的調整
內存參數的調整主要是指ORACLE資料庫的系統全局區(SGA)的調整。SGA主要由三部分構成:共享池、數據緩沖區、日誌緩沖區。
1、共享池由兩部分構成:共享SQL區和數據字典緩沖區,共享SQL區是存放用戶SQL命令的區域,數據字典緩沖區存放資料庫運行的動態信息。資料庫管理員通過執行下述語句:
select(sum(pins-reloads))/sum(pins)"LibCache"fromv$librarycache;
來查看共享SQL區的使用率。這個使用率應該在90%以上,否則需要增加共享池的大小。資料庫管理員還可以執行下述語句:
select(sum(gets-getmisses-usage-fixed))/sum(gets)"RowCache"fromv$rowcache;
查看數據字典緩沖區的使用率,這個使用率也應該在90%以上,否則需要增加共享池的大小。
2、數據緩沖區。資料庫管理員可以通過下述語句:
SELECTname,valueFROMv$sysstatWHEREnameIN('dbblockgets','consistentgets','physicalreads');
來查看資料庫數據緩沖區的使用情況。查詢出來的結果可以計算出來數據緩沖區的使用命中率=1-(physicalreads/(dbblockgets+consistentgets))。
這個命中率應該在90%以上,否則需要增加數據緩沖區的大小。
3、日誌緩沖區。資料庫管理員可以通過執行下述語句:
selectname,valuefromv$sysstatwherenamein('redoentries','redologspacerequests');
查看日誌緩沖區的使用情況。查詢出的結果可以計算出日誌緩沖區的申請失敗率:
申請失敗率=requests/entries,申請失敗率應該接近於0,否則說明日誌緩沖區開設太小,需要增加ORACLE資料庫的日誌緩沖區。
昆明北大青鳥java培訓班轉載自網路如有侵權請聯系我們感謝您的關注謝謝支持
B. 資料庫性能優化有哪些措施
1、調整數據結構的設計。這一部分在開發信息系統之前完成,程序員需要考慮是否使用ORACLE資料庫的分區功能,對於經常訪問的資料庫表是否需要建立索引等。
2、調整應用程序結構設計。這一部分也是在開發信息系統之前完成,程序員在這一步需要考慮應用程序使用什麼樣的體系結構,是使用傳統的Client/Server兩層體系結構,還是使用Browser/Web/Database的三層體系結構。不同的應用程序體系結構要求的資料庫資源是不同的。
3、調整資料庫SQL語句。應用程序的執行最終將歸結為資料庫中的SQL語句執行,因此SQL語句的執行效率最終決定了ORACLE資料庫的性能。ORACLE公司推薦使用ORACLE語句優化器(Oracle Optimizer)和行鎖管理器(row-level manager)來調整優化SQL語句。
4、調整伺服器內存分配。內存分配是在信息系統運行過程中優化配置的,資料庫管理員可以根據資料庫運行狀況調整資料庫系統全局區(SGA區)的數據緩沖區、日誌緩沖區和共享池的大小;還可以調整程序全局區(PGA區)的大小。需要注意的是,SGA區不是越大越好,SGA區過大會佔用操作系統使用的內存而引起虛擬內存的頁面交換,這樣反而會降低系統。
5、調整硬碟I/O,這一步是在信息系統開發之前完成的。資料庫管理員可以將組成同一個表空間的數據文件放在不同的硬碟上,做到硬碟之間I/O負載均衡。
6、調整操作系統參數,例如:運行在UNIX操作系統上的ORACLE資料庫,可以調整UNIX數據緩沖池的大小,每個進程所能使用的內存大小等參數。
資料庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫,它產生於距今六十多年前,隨著信息技術和市場的發展,特別是二十世紀九十年代以後,數據管理不再僅僅是存儲和管理數據,而轉變成用戶所需要的各種數據管理的方式。資料庫有很多種類型,從最簡單的存儲有各種數據的表格到能夠進行海量數據存儲的大型資料庫系統都在各個方面得到了廣泛的應用。
在信息化社會,充分有效地管理和利用各類信息資源,是進行科學研究和決策管理的前提條件。資料庫技術是管理信息系統、辦公自動化系統、決策支持系統等各類信息系統的核心部分,是進行科學研究和決策管理的重要技術手段。
在經濟管理的日常工作中,常常需要把某些相關的數據放進這樣的「倉庫」,並根據管理的需要進行相應的處理。
例如,企業或事業單位的人事部門常常要把本單位職工的基本情況(職工號、姓名、年齡、性別、籍貫、工資、簡歷等)存放在表中,這張表就可以看成是一個資料庫。有了這個"數據倉庫"我們就可以根據需要隨時查詢某職工的基本情況,也可以查詢工資在某個范圍內的職工人數等等。這些工作如果都能在計算機上自動進行,那我們的人事管理就可以達到極高的水平。此外,在財務管理、倉庫管理、生產管理中也需要建立眾多的這種"資料庫",使其可以利用計算機實現財務、倉庫、生產的自動化管理。
(2)存儲函數的性能優化擴展閱讀
資料庫,簡單來說是本身可視為電子化的文件櫃--存儲電子文件的處所,用戶可以對文件中的數據進行新增、截取、更新、刪除等操作。
資料庫指的是以一定方式儲存在一起、能為多個用戶共享、具有盡可能小的冗餘度的特點、是與應用程序彼此獨立的數據集合。
在經濟管理的日常工作中,常常需要把某些相關的數據放進這樣的"倉庫",並根據管理的需要進行相應的處理。
例如,企業或事業單位的人事部門常常要把本單位職工的基本情況(職工號、姓名、年齡、性別、籍貫、工資、簡歷等)存放在表中,這張表就可以看成是一個資料庫。有了這個"數據倉庫"我們就可以根據需要隨時查詢某職工的基本情況,也可以查詢工資在某個范圍內的職工人數等等。這些工作如果都能在計算機上自動進行,那我們的人事管理就可以達到極高的水平。此外,在財務管理、倉庫管理、生產管理中也需要建立眾多的這種"資料庫",使其可以利用計算機實現財務、倉庫、生產的自動化管理。
C. 存儲性能優化 MMKV源碼解析
好久沒有更新常用的第三方庫了。讓我們來聊聊MMKV這個常用的第三方庫。MMKV這個庫是做什麼的呢?他本質上的定位和sp有點相似,經常用於持久化小數據的鍵值對。其速度可以說是當前所有同類型中速度最快,性能最優的庫。
它的最早的誕生,主要是因為在微信iOS端有一個重大的bug,一個特殊的文本可以導致微信的iOS端閃退,而且還出現了不止一次。為了統計這種閃退的字元出現頻率以及過濾,但是由於出現的次數,發現原來的鍵值對存儲組件NSUserDefaults根本達不到要求,會導致cell的滑動卡頓。
因此iOS端就開始創造一個高新性能的鍵值對存儲組件。於此同時,Android端SharedPreferences也有如下幾個缺點:
因此Android也開始復用iOS的MMKV,而後Android有了多進程的寫入數據的需求,Android組又在這個基礎上進行改進。
這里是官方的性能的比較圖:
能看到mmkv比起我們開發常用的組件要快上數百倍。
那麼本文將會從源碼角度圍繞MMKV的性能為什麼會如此高,以及SharePrefences為什麼可能出現ANR的原因。
請注意下文是以MMKV 1.1.1版本源碼為例子分析。如果遇到什麼問題歡迎來到本文 https://www.jianshu.com/p/c12290a9a3f7 互相討論。
老規矩,先來看看MMKV怎麼使用。mmkv其實和SharePrefences一樣,有增刪查改四種操作。
MMKV作為一個鍵值對存儲組件,也對了存儲對象的序列化方式進行了優化。常用的方式比如有json,Twitter的Serial。而MMKV使用的是Google開源的序列化方案:Protocol Buffers。
Protocol Buffers這個方案比起json來說就高級不少:
使用方式可以閱讀下面這篇文章: https://www.jianshu.com/p/e8712962f0e9
下面進行比較幾個對象序列化之間的要素比較
而MMKV就是看重了Protocol Buffers的時間開銷小,選擇Protocol Buffers進行對象緩存的核心。
使用前請初始化:
當然mmkv除了能夠寫入這些基本類型,只要SharePrefences支持的,它也一定能夠支持。
同上,每一個key讀取的數據類型就是decodexxx對應的類型名字。使用起來十分簡單。
能夠刪除單個key對應的value,也能刪除多個key分別對應的value。containsKey判斷mmkv的磁碟緩存中是否存在對應的key。
mmkv和SharePrefences一樣,還能根據模塊和業務劃分對應的緩存文件:
這里創建了一個id為a的實例在磁碟中,進行數據的緩存。
當需要多進程緩存的時候:
MMKV可以使用Ashmem的匿名內存進行更加快速的大對象傳輸:
進程1:
最重要的一點,mmkv把SharePrefences的緩存遷移到mmkv中,之後的使用就和SharePrefences一致。
這里就是把SharedPreferences的myData數據遷移到mmkv中。當然如果我們需要保持SharePreferences的用法不變需要自己進行自定義一個SharePreferences。
mmkv的用法極其簡單,接下來我們關注他的原理。
首先來看看MMKV的初始化。
能看到實際上initialize分為如下幾個步驟:
能看到其實就是做這個判斷。由於此時設置的是libc++的打包方式。此時BuildConfig.FLAVOR就是StaticCpp,就不會載入c++_shared。當然,如果我們已經使用了c++_shared庫,則沒有必要打包進去,使用defaultPublishConfig "SharedCppRelease"會嘗試的查找動態鏈接庫_shared。這樣就能少2M的大小。
請注意一個前提的知識,jni的初始化,在調用了 System.loadLibrary之後,會通過dlopen把so載入到內存後,調用dlsym,調用jni中的JNI_OnLoad方法。
實際上這裡面做的事情十分簡單:
能從這些native方法中看到了所有MMKV的存儲方法,設置支持共享內存ashemem的存儲,支持直接獲取native malloc申請的內存
接下來就是MMKV正式的初始化方法了。
這個方法實際上調用的是pthread_once方法。它一般是在多線程環境中,根據內核的調度策略,選擇一個線程初始化一次的方法。
其實這裡面的演算法很簡單:
defaultMMKV此時調用的是getDefaultMMKV這個native方法,默認是單進程模式。從這里的設計都能猜到getDefaultMMKV會從native層實例化一個MMKV對象,並且讓實例化好的Java層MMKV對象持有。之後Java層的方法和native層的方法一一映射就能實現一個直接操作native對象的Java對象。
我們再來看看MMKV的mmkvWithID。
感覺上和defaultMMKV有點相似,也是調用native層方法進行初始化,並且讓java層MMKV對象持有native層。那麼我們可否認為這兩個實例化本質上在底層調用同一個方法,只是多了一個id設置呢?
可以看看MMKV.h文件:
這里就能看到上面的推測是正確的,只要是實例化,最後都是調用mmkvWithID進行實例化。默認的mmkv的id就是mmkv.default。Android端則會設置一個默認的page大小,假設4kb為例子。
所有的mmkvID以及對應的MMKV實例都會保存在之前實例化的g_instanceDic散列表中。其中mmkv每一個id對應一個文件的路徑,其中路徑是這么處理的:
如果發現對應路徑下的mmkv在散列表中已經緩存了,則直接返回。否則就會把相對路徑保存下來,傳遞給MMKV進行實例化,並保存在g_instanceDic散列表中。
我們來看看MMKV構造函數中幾個關鍵的欄位是怎麼初始化。
mmkvID就是經過md5後對應緩存文件對應的路徑。
能看到這里是根據當前的mode初始化id,如果不是ashmem匿名共享內存模式進行創建,則會和上面的處理類似。id就是經過md5後對應緩存文件對應的路徑。
注意這里mode設置的是MMKV_ASHMEM,也就是ashmem匿名共享內存模式則是如下創建方法:
實際上就是在驅動目錄下的一個內存文件地址。
接下來,在構造函數中使用了共享的文件鎖進行保護後,調用loadFromFile進一步的初始化MMKV內部的數據。
我們大致的了解MMKV中每一個欄位的負責的職責,但是具體如何進行工作下文都會解析。
在這裡面我們遇到了看起來十分核心的類MemoryFile,它的名字有點像 Ashmem匿名共享內存 一文中描述過Java層的映射的匿名內存文件。
我們先來看看MemoryFile的初始化。
MemeoryFile分為兩個模式進行初始化:
這里的處理很簡單:
能看到此時將會調用mmap系統調用,通過設置標志位可讀寫,MAP_SHARED的模式進行打開。這樣就file就在在內核中映射了一段4kb內存,以後訪問文件可以不經過內核,直接訪問file映射的這一段內存。
關於mmap系統調用的源碼解析可以看這一篇 Binder驅動的初始化 映射原理 。
能看到在這個過程中實際上還是通過ftruncate進行擴容,接著調用zeroFillFile,先通過lseek把指針移動當前容量的最後,並把剩餘的部分都填充空數據'\0'。最後映射指向的地址是有效的,會先解開後重新進行映射。
為什麼要做最後這個步驟呢?如果閱讀過我解析的mmap的源碼一文,實際上就能明白,file使用MAP_SHARED的模式本質上是給file結構體綁定一段vma映射好的內存。ftruncate只是給file結構體進行了擴容,但是還沒有對對應綁定虛擬內存進行擴容,因此需要解開一次映射後,重新mmap一次。
MMKV在如果使用Ashmem模式打開:
接下來loadFromFile 這個方法可以說是MMKV的核心方法,所有的讀寫,還是擴容都需要這個方法,從映射的文件內存,緩存到MMKV的內存中。
進入到這個方法後進行如下的處理:
在這里,遇到了一個比較有歧義的欄位m_version ,從名字看起來有點像MMKV的版本號。其實它指代的是MMKV當前的狀態,由一個枚舉對象代表:
注意m_vector是一個長度16的char數組。其實很簡單,就是把文件保存的m_vector獲取16位拷貝到m_metaInfo的m_vector中。因為aes的加密必須以16的倍數才能正常運作。
初始化分為這6點,我們從最後三點開始聊聊MMKV的初始化的核心邏輯。我們還需要開始關注MMKV中內存存儲的結構。
能看到首先從m_file獲取映射的指針地址,往後讀取4位數據。這4位數據就是actualSize 真實數據。但是如果是m_metaInfo的m_version 大於等於3,則獲取m_metaInfo中保存的actualSize。
其校驗的手段,是通過比較m_metaInfo保存的crcDigest和從m_file中讀取的crcDigest進行比較,如果一致說明數據無誤,則返回true,設置loadFromFile為true。
其實這裡面只處理m_metaInfo的m_version的狀態大於等於3的狀態。我們回憶一下,在readActualSize方法中,把讀取當前存儲的數據長度,分為兩個邏輯進行讀取。如果大於等於3,則從m_metaInfo中獲取。
crc校驗失敗,說明我們寫入的時候發生異常。需要強制進行recover恢復數據。
首先要清除crc校驗校驗了什麼東西:
MMKV做了如下處理,只處理狀態等級在MMKVVersionActualSize情況。這個情況,在m_metaInfo記錄上一次MMKV中的信息。因此可以通過m_metaInfo進行校驗已經存儲的數據長度,進而更新真實的已經記錄數據的長度。
最後讀取上一次MMKV還沒有更新的備份數據長度和crc校驗欄位,通過writeActualSize記錄在映射的內存中。
如果最後彌補的校驗還是crc校驗錯誤,最後會回調onMMKVCRCCheckFail這個方法。這個方法會反射Java層實現的異常處理策略
如果是OnErrorRecover,則設置loadFromFile和needFullWriteback都為true,盡可能的恢復數據。當然如果OnErrorDiscard,則會丟棄掉所有的數據。
D. 存儲體系如何體現不同性能資源和優化組合
不同性能資源組合優化思維,化整為0的存儲思維:數據存儲能力是現代計算機的重要能力。人們對存儲器的要求是:存儲容量要足夠大(越大越好),存儲速度要足夠快(能夠匹配CPU的運算速度)、存儲時間要足夠長(越長越好)、價格要足夠低(越低越好)。但滿足上述要求的存儲器是理想化的,因此現實中出現了各種性能的存儲器。典型的存儲器有:寄存器、隨機存取存儲器RAM、只讀存儲器ROM、高速緩沖存儲器Cache、硬碟及其它外存。這些存儲器構成一個存儲體系,其中外存不與CPU直接交換信息,內存與CPU直接交換信息。因此,內存就好像外存的一個「臨時緩沖區」。外存速度慢,以存儲塊為單位進行讀寫(一個存儲塊為一個扇區或其倍數),可以一次將更多的信息讀寫到內存,再被CPU處理。內存速度快,可與CPU中的寄存器按存儲單元/存儲字為單位交換信息,或者內存經過Cache,以Cache為緩沖區與CPU的寄存器交換信息。這樣「以批量換取速度、以空間換取時間」來實現存儲器與CPU之間速度的匹配,可使用戶感覺到讀寫速度很快同時容量又很大。相關資料:不同性能資源組合優化思維屬於一種計算機的裡面的一種相應的這種思維。就是通過這種相關的這種一些不同的這種組合,然後找到他這種相關的這種優化的特點,也就是說這個先進行相應的這種處理,然後再找到他的優點。這就要求他們能夠在這種復雜的環境下都能夠進行執行,這樣的不同的這種程序不同的相關的這種組合進行統一處理,通過這種控制調度就是可以實現這種資源整合。
E. 教程 | Excel性能優化方法(二)
方法六
允許額外數據
如果經常向工作表中添加多行或多列數據,則需要找出一種方法,使Excel 公式自動引用新數據區域,而不是每次都嘗試查找並更改公式。為此,可以在公式中使用遠超出當前數據邊界的較大區域。然而,在某些情況下,這可能會導致無效計算而且很難維護,這是因為刪除行和列可能會在你不注意的情況下減小區域。
方法七
使用結構化表引用
從 Excel 2007 開始,可以使用結構化表引用,此類引用可隨所引用表大小的增加或減小自動擴大和縮小。此解決方案有諸多優點:
方法八
使用整列引用和整行引用
例如 $A:$A。此引用返回 A 列中的所有行。因此,可以根據需要添加任意數量的數據,引用始終都包含這些數據。此解決方案包含以下優點和缺點:
方法九
用動態區域
通過在已命名區域的定義中使用 OFFSET 或 INDEX 和 COUNTA 函數,可以使已命名區域引用的區域動態擴大和縮小。例如,使用下列公式之一創建已定義名稱:
在公式中使用動態區域名稱時,它會自動擴大以包含新條目。對於動態區域,使用 INDEX 公式通常比使用 OFFSET 公式更可取,因為 OFFSET 的缺點是它是一個可變函數,每次重新計算都要對其進行計算。性能下降是因為動態區域公式中的 COUNTA 函數必須檢查多個行。可以通過將公式的 COUNTA 部分存儲在單獨單元格或已定義的名稱中,然後在動態區域內引用單元格或名稱來最大程度減少性能下降:
還可以使用 INDIRECT 等函數來構造動態區域,但 INDIRECT 是可變函數,且始終計算單線程。動態區域具有以下優點和缺點:
方法十
縮短查找計算時間
在 Office 365 版本 1809 和更高版本中,在從相同表區域查找多個列(或使用 HLOOKUP 查找行)時,Excel 的 VLOOKUP、HLOOKUP 和 MATCH 對未排序數據進行完全匹配要比以往快得多。也就是說,對於早期的 Excel 版本,查找仍然是常見的重要計算障礙。幸運的是,有許多方法可以改進縮短計算時間。如果使用完全匹配選項,則函數的計算時間與找到匹配之前掃描的單元格數量成正比。對於在較大區域進行查找,這一時間可能很長。對排序數據使用 VLOOKUP、HLOOKUP 和 MATCH 的近似匹配選項的查找時間很短,並且不會根據所查找的區域長度顯著增加。特徵與二進制搜索相同。
F. SQL Server 優化存儲過程的方法有哪些
優化存儲過程有很多種方法,下面介紹最常用的7種。
1.使用SET NOCOUNT ON選項
我們使用SELECT語句時,除了返回對應的結果集外,還會返回相應的影響行數。使用SET NOCOUNT ON後,除了數據集就不會返回額外的信息了,減小網路流量。
2.使用確定的Schema
在使用表,存儲過程,函數等等時,最好加上確定的Schema。這樣可以使SQL Server直接找到對應目標,避免去計劃緩存中搜索。而且搜索會導致編譯鎖定,最終影響性能。比如select * from dbo.TestTable比select * from TestTable要好。from TestTable會在當前Schema下搜索,如果沒有,再去dbo下面搜索,影響性能。而且如果你的表是csdn.TestTable的話,那麼select * from TestTable會直接報找不到表的錯誤。所以寫上具體的Schema也是一個好習慣。
3.自定義存儲過程不要以sp_開頭
因為以sp_開頭的存儲過程默認為系統存儲過程,所以首先會去master庫中找,然後在當前資料庫找。建議使用USP_或者其他標識開頭。
4.使用sp_executesql替代exec
原因在Inside Microsoft SQL Server 2005 T-SQL Programming書中的第四章Dynamic SQL裡面有具體描述。這里只是簡單說明一下:sp_executesql可以使用參數化,從而可以重用執行計劃。exec就是純拼SQL語句。
5.少使用游標
可以參考Inside Microsoft SQL Server 2005 T-SQL Programming書中的第三章Cursors裡面有具體描述。總體來說,SQL是個集合語言,對於集合運算具有較高的性能,而Cursors是過程運算。比如對一個100萬行的數據進行查詢,游標需要讀表100萬次,而不使用游標只需要少量幾次讀取。
6.事務越短越好
SQL Server支持並發操作。如果事務過多過長,或是隔離級別過高,都會造成並發操作的阻塞,死鎖。此時現象是查詢極慢,同時cup佔用率極低。
7.使用try-catch來處理錯誤異常
SQL Server 2005及以上版本提供對try-catch的支持,語法為:
begin try
----your code
end try
begin catch
--error dispose
end catch
一般情況可以將try-catch同事務結合在一起使用。
begin try
begin tran
--select
--update
--delete
--…………
commit
end try
begin catch
--if error
rollback
end catch
====================== 分割線 =======================
『自己的一些調優經驗』
1. 少使用游標是個很好的建議,為此,我自己也遇到過一些事故,是游標所造成的,由於,游標是逐行逐行操作的,當記錄較多時,經常會遇到超時的情況。
2. 多表join做查詢時,查詢的欄位盡量不要使用case when then else end的語法,或者使用用戶函數,例如:
select (case when fType=1 then '是' else '否' end) as fTypeName, dbo.F_GetFullName(fID) as fFullName from Table1 inner join Table2……
當兩個表的數據量非常大時,你可以在查詢分析器中明顯感覺到:直接查詢fType和fID與查詢上面兩個欄位的速度,很可能使用了一個case when then就導致超時。
針對這種情況,可以分兩種做法:
第一,把一些簡單的轉換可以放在程序中完成。
第二,如果需要通過ID查詢全名或者全稱,類似的,可以創建好視圖,直接查視圖,或者,先把所有的fFullName查出來放到臨時表中,直接join臨時表(如果這個數據不是很多的話),獲得fFullName。
3. 少使用一些嵌套的查詢,用臨時表緩存中間數據,例如:
select * from Table1
inner join (
select count(1) as count, Table2.ID2 from Table2 inner join Table3 on ID2=ID3 group by Table2.ID2
) as t1 on t1.ID1 = Table1.ID1
我曾經遇到這樣情況,上面的語句是那種情況的簡化版本,把其他不影響結果的表格都去掉了,發現一個奇怪的現象:嵌套查詢的結果集並不大,大約就200多行,Table1有6w條記錄,結果,這個查詢語句超時,查詢分析器中執行2分鍾也得不到結果。
後來,這樣一改,就Ok了,3秒出結果:
select count(1) as count, Table2.ID2 into #temp from Table2 inner join Table3 on ID2=ID3 group by Table2.ID2
select * from Table1
inner join #temp as t1 on t1.ID1 = Table1.ID1
這樣一改,效率提升了幾十倍,猜想:可能是嵌套的查詢是動態的,每一行的join可能都需要先執行嵌套的查詢,從而導致效率極差。
所以,如果查詢足夠復雜,join多個表,需要連接多個通過group by求和、求平均數等運算計算出來的中間數據,那麼,不妨多使用臨時表緩存中間數據。
4. 還有一些是必須遵守的一些默認規則,比如:
先過濾後連接。
查詢的欄位最要不要用「*」,指定需要用的欄位,減少網路流量。
『總結』
對於性能的追求是沒有極限的,做到你所能做到的,這是一個很好的習慣。
有些業務邏輯放在存儲過程中處理比較方便,而有些業務邏輯交給程序來處理,同樣會提升系統整體的效率,看實際情況而定。
總之,盡可能減少這些容易引發性能問題的隱患,系統就會跑得更穩定更有效率,一切從小細節做起。
G. 教程 | Excel性能優化方法(三)
01
使用 INDEX 和 MATCH 或 OFFSET 而不是 VLOOKUP
雖然 VLOOKUP 比 MATCH 和 INDEX,或 OFFSET 組合的速度稍快(大約快 5%)、更簡單,並使用更少的內存,但 MATCH 和 INDEX 所提供的額外靈活性通常可以顯著節省時間。例如,可以將完全 MATCH 的結果存儲在單元格中,並在幾個 INDEX 語句中重用。INDEX 函數是快速運行的不變函數,它可以加快重新計算的速度。 OFFSET 函數的運行速度也很快;但它是可變函數,因此有時會顯著增加處理計算鏈所需的時間。可輕松將 VLOOKUP 轉換為 INDEX 和 MATCH。以下兩個語句返回相同結果:
02
SORT的應用
由於完全匹配查找可能很慢,因此可以考慮使用以下選項來提高性能:
03
對缺少值的排序數據使用兩個查找
對於在數行內執行的查找,兩個近似匹配顯著快於一個完全匹配。 (分界點是大約 10-20 行。)
如果可以對數據排序,但由於不能確定要查找的值是否位於查找范圍內而仍無法使用近似匹配,則可以使用以下公式:
公式第一部分的運作方式是對查找列本身執行近似查找
可以使用以下公式檢查從查找列得到的結果是否與查找值相同(在這種情況下,你有一個完全匹配項):
如果此公式返回「True」,則找到了完全匹配項,所以可以再次執行近似查找,但這次從列中返回所需的結果。
如果從查找列得到的結果與查找值不匹配,則表示它是缺失值,公式將返回「notexist」。
注意,如果查找的值小於列表中的最小值,則會收到錯誤。可以使用 IFERROR 來處理此錯誤,或者向列表添加一個小的測試值。
04
對於缺少值的未排序數據,使用 IFERROR 函數
如果必須對未排序數據使用完全匹配查找,但是不能確定查找值是否存在,通常必須處理找不到匹配項時返回的 #N/A。從 Excel 2007 開始,可以使用 IFERROR 函數,該函數既快又簡單。
在早期版本中,一個簡單但較慢的方法是使用包含兩個查找的 IF 函數。
如果使用完全 MATCH 一次,將結果存儲在單元格中,然後在執行 INDEX 之前測試結果,則可以避免雙重完全查找。
如果無法使用兩個單元格,則使用 COUNTIF。它通常比完全匹配查找速度快。
05
使用 MATCH 和 INDEX 對多個列進行完全匹配查找
通常可以多次重復使用存儲的完全 MATCH。例如,如果要對多個結果列執行完全查找,則可以使用一個 MATCH 和多個 INDEX 語句(而不是多個 VLOOKUP 語句)來節省時間。為 MATCH 添加一個額外的列來存儲結果 ( stored_row ),並對每個結果列使用以下語句:
或者,可以在數組公式中使用 VLOOKUP。(必須使用 Ctrl+-Shift+Enter 輸入數組公式。Excel 將添加 { and },以顯示這是一個數組公式)。
H. Sql sever怎麼優化存儲過程。。大概步驟
1、精減變數,排除重復
2、優化SQL語句,將效率低的語句找出,盡量不用查詢全部、嵌套等SQL
3、將重復語句盡量用動態語句實現
4、盡量少用SQL直接計算,能用函數就用函數
等等
具體還是需要根據業務需求調整
I. 教程 | Excel性能優化方法(四)
01
對一組連續的行或列使用 INDEX
還可以從一個查找操作返回多個單元格。要查找多個連續的列,可以使用數組公式中的 INDEX 函數一次返回多個列(使用 0 作為列號)。還可以使用 INDEX 函數一次返回多個行。
這將從之前的 MATCH 語句創建的存儲行返回列 A 到列 J
02
使用子集區域進行多索引查找
在大型工作表中,可能經常需要使用多個索引來進行查找,例如查找某個國家/地區的產品量。為此,可以連接索引並使用連接的查找值執行查找。然而,有兩個原因會導致其效率低下:
計算查找的子集區域通常更有效(例如,通過查找國家/地區的第一行和最後一行,然後在該子級區域內查找產品)。
03
考慮三維查找選項
除行和列外,若還要查找要使用的表,則可以使用以下方法,這些方法重點處理如何使 Excel 查找或選擇表。如果要查找的每個表(第三維)都存儲為一組已命名結構化表、區域名稱或存儲為表示區域的文本字元串表,則可以使用 CHOOSE 或 INDIRECT 函數。使用 CHOOSE 和區域名稱是一種有效方法。 CHOOSE 是不可變函數,但最適用於相對較少的表。此示例動態使用 TableLookup_Value 來選擇要用於查找表的區域名稱 ( TableName1, TableName2, ... )。
下面的示例使用 INDIRECT 函數和 TableLookup_Value 動態創建要用於查找表的工作表名稱。這種方法的優點是簡單,能夠處理大量表。因為 INDIRECT 是可變的單線程函數,所以即使沒有數據發生變化,查找也是每次計算時計算的單線程。使用此方法速度較慢。
還可以使用 VLOOKUP 函數查找要用於表的工作表名稱或文本字元串,然後使用 INDIRECT 函數將結果文本轉換為區域。
另一方法是將所有表聚合到一個大型表中,該表包含另一標識各個表的列。然後可以使用前面的示例中所示的多索引查找方法。
04
使用通配符查找
MATCH、VLOOKUP 和 HLOOKUP 函數允許你在按字母順序完全匹配的情況下使用通配符 ? (任何單個字元)和 *(沒有字元或任意數量的字元)。有時,可使用此方法避免多個匹配項。
05
優化數組公式和 SUMPRODUCT
數組公式和 SUMPRODUCT 函數功能強大,但必須謹慎處理。單個數組公式可能需要多次計算。優化數組公式計算速度的關鍵在於,確保盡可能減少在數組公式中計算的單元格和表達式的數量。請記住,數組公式與可變公式有點相似:如果它引用的任何一個單元格發生更改、可變或者經過重新計算,則數組公式會計算該公式中的所有單元格並計算執行計算所需的所有虛擬單元格。要優化數組公式的計算速度,請執行以下操作:將數組公式中的表達式和區域引用提取到單獨的輔助列和行中。這樣可以更好地利用 Excel 中的智能重新計算過程。不要引用完整行,或引用超出需要的行和列。數組公式被迫計算公式中的所有單元格引用,即使單元格為空或未使用。從 Excel 2007 開始,有 100 萬行可用,引用整個列的數組公式的計算速度極其緩慢。從 Excel 2007 開始,如果可以,請使用結構化引用來最大程度地減少數組公式計算的單元格數。在 Excel 2007 之前的版本中,盡可能使用動態區域名稱。盡管它們可變,但這是值得的,因為它們最大程度縮小了區域大小。注意同時引用行和列的數組公式:這將強制計算矩形區域。盡可能使用 SUMPRODUCT;它比等效的數組公式速度稍微快一點。