sql優(yōu)化

1、 優(yōu)化器

優(yōu)化器(Optimizer)是SQL分析和執(zhí)行的優(yōu)化工具,它負責(zé)生成、制定SQL的執(zhí)行計劃。主要有以下兩種優(yōu)化器:
RBO: Rule-Based Optimization 基于規(guī)則的優(yōu)化器
CBO: Cost-Based Optimization 基于成本的優(yōu)化器
Oracle數(shù)據(jù)庫兩種優(yōu)化器都支持,默認啟用CBO,mysql數(shù)據(jù)庫只支持CBO。
假設(shè)emp表有1000萬條數(shù)據(jù),在deptno字段有單列索引emp_deptno_idx。

select * from emp where deptno=10;

RBO中有一條規(guī)則:有索引就用索引。以上面這條sql為例,RBO優(yōu)化器會先取出索引emp_deptno_idx,通過where條件deptno=10過濾出符合條件數(shù)據(jù),根據(jù)過濾后數(shù)據(jù)的rowid再從emp表里取整條數(shù)據(jù)(這個操作叫做"回表")。當(dāng)emp表的deptno字段值分布比較均勻,譬如有10萬種值,每種值大約10條,此時基于RBO的優(yōu)化走索引會取得很好的優(yōu)化效果;但是當(dāng)deptno字段值比較集中,有99.99萬條數(shù)據(jù)是10時,此時基于RBO的優(yōu)化走索引非但不能取得好的優(yōu)化效果,反而會因先取索引進行比較再回表取數(shù)據(jù)降低查詢性能。
對于CBO優(yōu)化器,在制定執(zhí)行計劃的時候會先計算下成本,對于以上sql,以直接走全表查詢和先走索引再回表查詢這兩種執(zhí)行方式為例,CBO優(yōu)化器會先取得emp表deptno字段數(shù)據(jù)的分布情況數(shù)據(jù),然后根據(jù)取得的數(shù)據(jù)計算究竟是直接走全表代價比較低還是先走索引再回表代價比較低,最后選擇成本最小的方式作為執(zhí)行計劃。當(dāng)deptno字段值分布比較均勻時,CBO會先走索引再回表,當(dāng)deptno字段值分布比較集中時,CBO會直接走全表。

2、執(zhí)行計劃

如果把一條sql比作一元二次方程ax2+bx+c=0(a≠0),那么執(zhí)行計劃就好比我們的求解公式:


一元二次方程求根公式

顯然,對于一元二次方程,除了直接用求根公式,我們還可以用配方法等其他方法求解,具體選用哪種方法求解,那就看哪種方法更快速了。

3、sql執(zhí)行過程

sql執(zhí)行過程

當(dāng)?shù)谝粭lsql進來時,客戶端->連接器->緩存->分析器->優(yōu)化器->執(zhí)行器,此時數(shù)據(jù)庫會為該sql生成一個執(zhí)行計劃。當(dāng)相同的sql再次進來查詢時,數(shù)據(jù)庫會先從緩存里面查找,若找到上次執(zhí)行的結(jié)果就直接返回。
當(dāng)?shù)诙lsql進來時,如果這條sql和第一條sql用的是同一個 PreparedStatement,只是參數(shù)值不同,此時會直接在緩存中找出執(zhí)行第一條sql時生成的執(zhí)行計劃,用于第二條sql的執(zhí)行。即執(zhí)行路徑為客戶端->連接器->緩存->執(zhí)行器,少了分析器和優(yōu)化器這兩個極度耗時的硬解析步驟,對于結(jié)構(gòu)復(fù)雜但是數(shù)據(jù)量少的sql,sql執(zhí)行效率比不使用PreparedStatement反復(fù)解析sql生成執(zhí)行計劃能獲得大幅度的性能上的提升(硬解析一方面會消耗CPU資源,另一方面,保存大量類似的執(zhí)行計劃,需要消耗大量的內(nèi)存資源,所以,理論上,所有sql的執(zhí)行都應(yīng)該使用PreparedStatement而不用Statement)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容