不会依据场景选技术
索引與更新
drop table test1 purge; drop table test2 purge; drop table test3 purge; drop table t purge; create table t as select * from dba_objects; create table test1 as select * from t; create table test2 as select * from t; create table test3 as select * from t; create index idx_owner on test1(owner); create index idx_object_name on test1(object_name); create index idx_data_obj_id on test1(data_object_id); create index idx_created on test1(created); create index idx_last_ddl_time on test1(last_ddl_time); create index idx_status on test1(status); create index idx_t2_sta on test2(status); create index idx_t2_objid on test2(object_id); set timing on --語句1(test1表有6個索引) insert into test1 select * from t; commit; --語句2(test2表有2個索引) insert into test2 select * from t; commit; --語句3(test3表有無索引) insert into test3 select * from t; commit;-------------------------------------------------------------------------------------------------------------------------------一次與出賬相關的小故事 drop table t purge; create table t as select * from dba_objects; insert into t select * from t; insert into t select * from t; commit; --請從這里開始注意累加的時間(從建索引到插入記錄完畢) set timing on create index idx_t_owner on t(owner); create index idx_t_obj_name on t(object_name); create index idx_t_data_obj_id on t(data_object_id); create index idx_t_created on t(created); create index idx_t_last_ddl on t(last_ddl_time);--語句1(t表有6個索引) insert into t select * from t; commit;--以下進行試驗2 drop table t purge; create table t as select * from dba_objects; insert into t select * from t; insert into t select * from t; commit;---也從這里開始這里開始注意累加的時間(從插入記錄完畢到建索引完畢)set timing on --語句1(t表有6個索引,此時先不建) insert into t select * from t;create index idx_t_owner on t(owner); create index idx_t_obj_name on t(object_name); create index idx_t_data_obj_id on t(data_object_id); create index idx_t_created on t(created); create index idx_t_last_ddl on t(last_ddl_time);不會依據場景選擇技術(關于索引壞處考慮)
索引與排序
set linesize 266 drop table t purge; create table t as select * from dba_objects;select t1.name, t1.STATISTIC#, t2.VALUEfrom v$statname t1, v$mystat t2where t1.STATISTIC# = t2.STATISTIC#and t1.name like '%sort%';create index idx_object_id on t(object_id);select t1.name, t1.STATISTIC#, t2.VALUEfrom v$statname t1, v$mystat t2where t1.STATISTIC# = t2.STATISTIC#and t1.name like '%sort%';?
分區效率變低
drop table part_tab purge; create table part_tab (id int,col2 int,col3 int)partition by range (id)(partition p1 values less than (10000),partition p2 values less than (20000),partition p3 values less than (30000),partition p4 values less than (40000),partition p5 values less than (50000),partition p6 values less than (60000),partition p7 values less than (70000),partition p8 values less than (80000),partition p9 values less than (90000),partition p10 values less than (100000),partition p11 values less than (maxvalue)); insert into part_tab select rownum,rownum+1,rownum+2 from dual connect by rownum <=110000; commit; create index idx_par_tab_col2 on part_tab(col2) local; create index idx_par_tab_col3 on part_tab(col3) ;drop table norm_tab purge; create table norm_tab (id int,col2 int,col3 int); insert into norm_tab select rownum,rownum+1,rownum+2 from dual connect by rownum <=110000; commit; create index idx_nor_tab_col2 on norm_tab(col2) ; create index idx_nor_tab_col3 on norm_tab(col3) ;set autotrace traceonly statistics set linesize 1000 set timing on select * from part_tab where col2=8 ; select * from norm_tab where col2=8 ;select * from part_tab where col2=8 and id=2; select * from norm_tab where col2=8 and id=2;--查看索引高度等信息 select index_name,blevel,leaf_blocks,num_rows,distinct_keys,clustering_factorfrom user_ind_statisticswhere table_name in( 'NORM_TAB');select index_name,blevel,leaf_blocks,num_rows,distinct_keys,clustering_factor FROM USER_IND_PARTITIONS where index_name like 'IDX_PAR_TAB%';select * from part_tab where col3=8 ;不會依據場景選擇技術(說說分區更慢的場景)
條數性能大比拼
--最慢速度(無索引) drop table t purge; create table t as select * from dba_objects; alter table T modify OBJECT_NAME not null; select count(*) from t; set autotrace traceonly set linesize 1000 set timing on select COUNT(*) FROM T; /--快了一點(有普通索引) drop table t purge; create table t as select * from dba_objects; alter table T modify OBJECT_NAME not null; create index idx_object_name on t(object_name); set autotrace traceonly set timing on select count(*) from t; /--又快一點(有了一個合適的位圖索引) drop table t purge; create table t as select * from dba_objects;Update t Set object_name='abc'; Update t Set object_name='evf' Where rownum<=20000; create bitmap index idx_object_name on t(object_name); set autotrace traceonly set timing on select count(*) from t; / 注:如果記錄數不重復或者說重復度很低,ORACLE會選擇全表掃描,如果用 來強制,可以發現性能很低下。 alter session set statistics_level=all ; set linesize 1000 set pagesize 1 select /*+index(t,idx_object_name)*/ count(*) from test t; select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));--再快一點(物化視圖,注意使用的場景)drop materialized view MV_COUNT_T; drop table t purge; create table t as select * from dba_objects;Update t Set object_name='abc'; Update t Set object_name='evf' Where rownum<=20000;create materialized view mv_count_tbuild immediaterefresh on commitenable query rewriteasselect count(*) FROM T;set autotrace traceonly set linesize 1000 select COUNT(*) FROM T; /--又再快一點(緩存結果集,也是要注意使用的場景) drop table t purge; create table t as select * from dba_objects; select count(*) from t; set linesize 1000 set autotrace traceonly select /*+ result_cache */ count(*) from t; /--速度之王來咯!(原來需求才是王道) select count(*) from t where rownum=1;從單車到飛船的SQL優化之旅
未優化前,單車慢悠悠(55秒)
第一招:綁定變量,單車變摩托(11秒)
ORACLE體系落地應用六個精進妙招
第二招:靜態改寫,摩托變汽車(9秒)
第三招:批量提交,汽車變動車(4秒)
第四招:集合寫法,動車變飛機(0.2秒)
第五招:直接路徑,飛機變火箭(0.1秒)
第六招:并行設置,火箭變飛船(0.02秒)
?
?
?
?
?
?
?
?
?
總結