1. 程式人生 > >Oracle SQL查詢優化方法1

Oracle SQL查詢優化方法1

系統優化中很重要的方面是SQL語句的優化,對於海量資料,優質的SQL能夠有效的提高系統的可用性。

總結的有點羅嗦,列個簡單的目錄啦~

目錄

知識準備

1. sql執行過程

1)執行過程

  當一個oracle例項接收到一條sql後,執行過程如下:

  1) create  a cursor  建立遊標

  2) parse the statement 分析語句

  3)  describe results of a query 描述查詢的結果集

  4)define output of a query 定義查詢的輸出資料

  5)bind any variables 繫結變數

  6)parallelize the statement 並行執行語句

  7)run the statement 執行語句

  8)fetch rows of a query 取查詢結果

  9)close the cursor 關閉遊標

2.SQL 共享

  1. 為不重複解析相同的SQL語句,oracle 將執行過的SQL語句存放在記憶體的共享池(shared buffer pool)中,可以被所有資料庫使用者共享

  2. 當執行一個SQL語句時,如果它和之前執行過的語句完全相同(注意同義詞和表是不同物件),oracle就能獲得已經被解析的語句;

3.bind variables繫結變數

     1)解決重編譯問題

eg1:

insert into tab1(col1,col2) values (val1,val2); --普通方式

insert into tab1(col1,col2) values (:v1,:v2);--繫結變數,只需編譯一次

eg2:使用PreparedStatement

PreparedStatement ps = con.prepareStatement("insert into tab1 (col1, col2) values (?,?)");

  2)共享遊標

  好處:減少解析;提高記憶體使用率;動態記憶體調整

  假如輸入如下兩個sql:

select * from tab1 where id = :c;
select * from tab1 where id = :d;

  這兩句sql會被轉化為:

select * from tab1 where id = :b;

4.訪問資料表方式

 1)全表掃描——順序訪問表中每條記錄

  oracle採用一個讀入多個數據塊的方式優化全表掃描

  2)通過rowid訪問表——rowid包含了表中記錄的物理位置資訊, 基於rowid訪問方式可以提高訪問表的效率

  oracle通過索引實現了資料和存放資料位置rowid之間的聯絡,通常索引提供了快速訪問rowid的方法

5. select sql執行順序

1)select子句

複製程式碼
(8)SELECT (9)DISTINCT  (11)<Top Num> <select list>
(1)FROM <left_table>
(3)<join_type> JOIN <right_table>
(2)ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>
複製程式碼

2)執行順序說明

複製程式碼
  1FROM [left table]——from前的表做笛卡爾集 ——虛擬表VT1

  2) ON <join condition>——篩選——VT2

  3) [join type] JOIN [right table]——連線——VT3 詳細見 oracle連線

  4) WHERE ——where篩選——VT4

  5GROUP BY ——按照GROUP BY子句中的列對VT4中行分組——VT5

  6)CUBE|ROLLUP——分組,eg:ROLLUP(A, B),首先會對(A、B)進行GROUP BY,然後對(A)進行GROUP BY,最後對全表GROUP BY

                CUBE(A,B), 首先對(A、B)GROUP BY, 然後(A)、(B) GROUP BY, 最後全表GROUP BY;

                ——VT6

  7) HAVING——HAVING篩選——VT7

  8SELECT——VT8

  9) DISTINCT——移除重複的行——VT9

  10ORDER BY——按照order by子句中的列將VT9中列表排序,生成遊標——VC10

  11) TOP ——從VC10的開始處選擇一定數量或者比例的行——VT11,返回結果
複製程式碼

3)注意事項

  1. 只有ORDER BY 子句中可以使用select列表中列的別名

     如果要在其他地方使用需要使用如下方式:

SELECT * FROM (SELECT NAME, SALARY AS s FROM EMP ) vt WHERE vt.s<5000;

  2.  使用了ORDER BY子句的查詢不能用作表表達式(檢視、內聯表值函式、子查詢、派生表和共用表示式),如下的語句都會產生錯誤

create table tab1 as select * from student order by score;

select * from (select * from student order by score);

6.索引使用

  正確使用索引可以有效提高系統性能,詳細見 

常用sql用法和及注意事項

1.exits和in用法

1)說明:

  1. exists對外表做迴圈,每次迴圈對內表查詢;in將內表和外表做hash連線

  2. 使用exists oracle會先檢查主查詢; 使用in,首先執行子查詢,並將結果儲存在臨時表中

2)使用:

  表class和student表

         

  下面查詢student中classno在class中的資料

  1. 使用exists和not exists

select name, classno from student where exists (select * from class where student.classno= class.classno);

  結果:

  

select name, classno from student where not exists (select * from class where student.classno= class.classno);

  結果:

  

select name, classno  from student where classno  in (select classno from class);

  2. 使用in 和not in

select name, classno  from student where classno not in (select classno from class);

   

  結果:

  

3)比較

  1. 如果兩個表大小相當,in和exists差別不大

  2. 如果兩個表大小相差較大則子查詢表大的用exists,子查詢表小的用in

  3.儘量不要使用not in

2.union和union all

1)說明:

  1. 使用場景:需要將兩個select語句結果整體顯示時,可以使用union和union all

  2. union對兩個結果集取並集不包含重複結果同時進行預設規則的排序;而union all對兩個結果集去並集,包括重複行,不進行排序

  3.  union需要進行重複值掃描,效率低,如果沒有要刪除重複行,應該使用union all

  4. insersect和minus分別交集和差集,都不包括重複行,並且進行預設規則的排序

2)使用注意事項

  1.可以將多個結果集合並

  2. 必須保證select集合的結果有相同個數的列,並且每個列的型別是一樣的(列名不一定要相同,會預設將第一個結果的列名作為結果集的列名)

3)例子:

表student

eg1:

select name, score from student where score> 60
union all 
select name, score from student where score <200;

結果:(有重複,沒有排序)

select name, score from student where score> 60
union
select name, score from student where score <200;

結果:(沒有重複,並且排序了)

3.with as

1)說明:

  1. with table as 可以建立臨時表,一次分析,多次使用

  2. 對於複雜查詢,使用with table as可以抽取公共查詢部分,多次查詢時可以提高效率

  3. 增強了易讀性

2)語法:

with tabName asselect ...)

3)例子:

表student

eg1: 

select rownum, name, score from (select rownum, name,score from student where score >70 order by score); 

可以更換成:

with table_s as (select rownum, name,score from student where score >70 order by score)
select name, score from table_s;

結果:

 4)多個with table as 一起使用時用逗號隔開,並且只能使用一個with如下例子

eg1:

複製程式碼
with vt1 as (select * from student where score >=60),
vt2 as (select * from class),
vt3 as (select * from teacher)
select vt1.name, vt1.score, vt2.classname, vt3.teachername  from vt1,vt2,vt3 where vt1.classno= vt2.classno and vt1.teacherid=vt3.teacherid;
複製程式碼

eg2:

複製程式碼
with vt as (select t.* 
from travelrecord t where t.starttime>=to_date('2014-02-01','yyyy-mm-dd') and t.endtime<=to_date('2014-04-30','yyyy-mm-dd')+1 and to_char(starttime,'hh24')>='08' and to_char(endtime,'hh24')<='11' and t.vehiclenum='100088110000'),
vt1 as (select  sum(vt4.traveltime) as stoptime from ((select * from vt where vt.state='0')vt4)),
vt2 as (select sum(vt.traveltime)as "ONLINETIME1",sum(vt.distance)as "DISTANCE1"from vt)
select vt1.stoptime,vt2.distance1, vt2.onlinetime1 from vt2, vt1;
複製程式碼

4. order by

1)說明:

  1. order by 決定oracle如何將查詢結果排序

  2. 不指定asc或者desc時預設asc

2)使用:

  1. 單列升序(可以去掉asc)

select * from student order by score asc;

  2. 多列升序

select * from student order by score,  deptno;

  3. 多列降序

select * from student order by score desc,  deptno  desc;

  4. 混合

select * from student order by score asc,  deptno  desc;

3)對NULL的處理

  1. oracle在order by 時認為null是最大值,asc時排在最後,desc時排在最前

  eg:

select * from student order by score asc;

結果:

  2. 使用nulls first (不管asc或者desc,null記錄排在最前)或者nulls last 可以控制null的位置,eg:

select * from student order by score asc nulls first;

結果如下:

4)將某行資料置頂(decode)

  eg1:

select * from student order by decode(score,100,1,2);

結果:

eg2: (某一行置頂,其他的升序)

select * from student order by decode(score,100,1,2), score;

5)注意事項

  1. 任何在order by 語句的非索引項都將降低查詢速度

  2. 避免在order by 子句中使用表示式

5. group by

1)說明:

  1.用於對where執行結果進行分組

2)簡單例子:

eg1:

select sum(score), deptno from student group by deptno;

結果: 

  

eg2:

select deptno,sum(score) from student where deptno>1  group by deptno;

結果:

6.where和having

1)說明:

  1. where和having都是用來篩選資料,但是執行的順序不同 where --group by--having(即分組計算前計算where語句,分組計算後計算having'語句),詳情檢視章節一sql執行順序

  2. having一般用來對分組後的資料進行篩選

  3. where中不能使用聚組函式如sum,count,max等

2)例子:

eg1: 對 5 中group by 的資料篩選

select deptno,
            
           

相關推薦

Oracle SQL查詢優化方法1

系統優化中很重要的方面是SQL語句的優化,對於海量資料,優質的SQL能夠有效的提高系統的可用性。 總結的有點羅嗦,列個簡單的目錄啦~ 目錄 知識準備 1. sql執行過程 1)執行過程   當一個oracle例項接收到一條sql後,執行過程

MySQL大資料量分頁查詢方法及其優化 ---方法1: 直接使用資料庫提供的SQL語句 ---語句樣式: MySQL中,可用如下方法: SELECT * FROM 表名稱 LIMIT M,N ---適

測試實驗 1.   直接用limit start, count分頁語句, 也是我程式中用的方法: select * from product limit start, count 當起始頁較小時,查詢沒有效能問題,我們分別看下從10, 100, 1000, 10000開始分頁的執行時間(每頁取20條), 如

oracle SQL查詢number字段精度丟失之解決方法

ont spa ora bsp acl 存在 解決辦法 from eight 解決辦法: -- 3.3:表示原始數據 --fm9999999990.0000:表示保留到小數點後4位,若不存在則用0補位。 select to_char(nvl(3.3,0),‘fm9999

013-- mysql常用的查詢優化方法 淺談MySQL中優化sql語句查詢常用的30種方法

淺談MySQL中優化sql語句查詢常用的30種方法   1.對查詢進行優化,應儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。 2.應儘量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全

Oracle大欄位(clob)模糊查詢優化方法

對於內容很多的時候clob打欄位模糊查詢很慢,整理一個小方法: 1,在查詢的列上建索引         2,對於要查詢的clob欄位使用一下語句建立索引   CREATE INDEX idx_zs_info_note ON zs_info(note) INDEXTYPE

Sql常用查詢優化方法

對查詢進行優化,應儘量避免全表掃描,首先應考慮在where 及order by 涉及的列上建立索引:  .嘗試下面的技巧以避免優化器錯選了表掃描: ·   使用ANALYZE TABLE tbl_name為掃描的表更新關鍵字分佈。 ·   對掃描的表使用FORCE INDEX

提高mysql千萬級大數據SQL查詢優化30條經驗

pro 字符串 插入數據 run 較差 存儲 同時 例程 鎖定 1.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。 2.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進

mysql-大量數據的sql查詢優化

not in red 固然 替換 其他 百分號 pro don 客戶 1、應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 2、對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉

Oracle-SQL程序優化3

acl .cn 產生 bsp 執行 create cpu rac oracle 最近一個星期ETL無論在淩晨或是在中午的JOB執行過程中經常卡住,導致不能按時完成系統引擎的運行,對業務產生影響。 通過生成AWR報告,發現有三條SQL消耗大量的CPU,而且還沒有執行完成被終止

Oracle-SQL程序優化4

插入 oracl 是什麽 而且 查看 建表 sap logs 兼容性問題 從事一年DBA工作,經驗尚淺,但是遇到問題總還是能夠解決,今天就談下我遇到的一個比較奇葩的問題。 運維人員告知我下午過後ETL一直卡住沒有繼續,那時我以為又是什麽兼容性問題引起的,就重跑一下ETL,誰

mysql千萬級大數據SQL查詢優化

意義 表達式 -1 大數據量 並且 系統 -s get 連接 1.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。 2.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全

Sql查詢優化

子句 order by 連續 char 設置 nio 引擎 重復 超過 一,數據庫設計角度   1.盡量避免全表查詢,首先考慮在where一級order by的列上建立索引。   2.盡量避免在where的子句中進行null判斷,導致引擎放棄索引進行全表掃描。列如:sele

常用的SQL語句優化方法

臨時表 數據 arch ediff 重復 red pac eight code 1、應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 2、對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order

Orcle的sql語句優化1

name 即使 緩沖 mode 數據塊 如何 ack 訪問 從右到左 1. 選用適合的ORACLE優化器 ORACLE的優化器共有3種: a. RULE (基於規則) b. COST (基於成本) c. CHOOSE (選擇性) 設置缺省的優化器,可以通過對init.o

MySQL查詢優化方法總結

系統表 所有 全文檢索 更新 系統 and 插入 upd 一個 1.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 2.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及頻繁的

sql 查詢優化

優化表 where 鏈接 chan 合計 end 滿足 into 由於 原文鏈接: http://www.promptness.cn/article/4 1.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。2.應盡量

oracle查詢優化

ora acl 合並 發現 自己 向上 file lin HERE ORACLE有個高速緩沖的概念,這個高速緩沖就是存放執行過的SQL語句,那oracle在執行sql語句的時候要做很多工作,例如解析sql語句,估算索引利用率,綁定變量,讀取數據塊等等這些操作。假設高速緩沖裏

30個MySQL千萬級大數據SQL查詢優化技巧詳解

!= 結果 exist 進行 cluster date 有意義 參數 rop 本文總結了30個mysql千萬級大數據SQL查詢優化技巧,特別適合大數據裏的MYSQL使用。 1.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建

總結很好的SQL優化方法。。。

轉自:https://www.cnblogs.com/cnzxy/p/9392721.html --導致查詢緩慢的原因 1、資料量過大 2、表設計不合理 3、sql語句寫得不好 4、沒有合理使用索引 -- 針對SQL語句的優化 1、查詢語句中不要使用 * 2、儘量減

MySQL效能管理及架構設計(三):SQL查詢優化、分庫分表 - 完結篇

一、SQL查詢優化(重要) 1.1 獲取有效能問題SQL的三種方式 通過使用者反饋獲取存在效能問題的SQL; 通過慢查日誌獲取存在效能問題的SQL; 實時獲取存在效能問題的SQL; 1.1.2 慢查日誌分析工具 相關配置引數: slow