oracle中如何優化sql語句的,用什么方法
2. 選擇最有效率的表名順序(只在基于規則的優化器中有效) ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,因此FROM子句中寫在最后的表(基礎表 driving table)將被最先處理. 在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表.當ORACLE處理多個表時, 會運用排序及合并的方式連接它們.首先,掃描第一個表(FROM子句中最后的那個表)并對記錄進行派序,然后掃描第二個表(FROM子句中最后第二個表),最后將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合并. 例如: 表 TAB1 16,384 條記錄 表 TAB2 1 條記錄 選擇TAB2作為基礎表 (最好的方法) select count(*) from tab1,tab2 執行時間0.96秒 選擇TAB2作為基礎表 (不佳的方法) select count(*) from tab2,tab1 執行時間26.09秒 如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表. 例如: EMP表描述了LOCATION表和CATEGORY表的交集. SELECT * FROM LOCATION L , CATEGORY C, EMP E WHERE *_NO BETWEEN 1000 AND 2000 AND *_NO = *_NO AND * = * 將比下列SQL更有效率 SELECT * FROM EMP E , LOCATION L , CATEGORY C WHERE *_NO = *_NO AND * = * AND *_NO BETWEEN 1000 AND 2000 3. WHERE子句中的連接順序. ORACLE采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾. 例如: (低效,執行時間156.3秒) SELECT … FROM EMP E WHERE SAL > 50000 AND JOB = 'MANAGER' AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=*); (高效,執行時間10.6秒) SELECT … FROM EMP E WHERE 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=*) AND SAL > 50000 AND JOB = 'MANAGER'; 4. SELECT子句中避免使用 ‘ * ‘ 當你想在SELECT子句中列出所有的COLUMN時,使用動態SQL列引用 ‘*’ 是一個方便的方法.不幸的是,這是一個非常低效的方法. 實際上,ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間. 5. 減少訪問數據庫的次數 當執行每條SQL語句時, ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變量 , 讀數據塊等等. 由此可見, 減少訪問數據庫的次數 , 就能實際上減少ORACLE的工作量. 例如, 以下有三種方法可以檢索出雇員號等于0342或0291的職員. 方法1 (最低效) SELECT EMP_NAME , SALARY , GRADE FROM EMP WHERE EMP_NO = 342; SELECT EMP_NAME , SALARY , GRADE FROM EMP WHERE EMP_NO = 291; 方法2 (次低效) DECLARE CURSOR C1 (E_NO NUMBER) IS SELECT EMP_NAME,SALARY,GRADE FROM EMP WHERE EMP_NO = E_NO; BEGIN OPEN C1(342); FETCH C1 INTO …,..,.. ; OPEN C1(291); FETCH C1 INTO …,..,.. ; CLOSE C1; END; 方法3 (高效) SELECT *_NAME , * , *, *_NAME , * , * FROM EMP A,EMP B WHERE *_NO = 342 AND *_NO = 291; 注意: 在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加每次數據庫訪問的檢索數據量 ,建議值為200. 6. 使用DECODE函數來減少處理時間 使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表. 例如: SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0020 AND ENAME LIKE 'SMITH%'; SELECT COUNT(*),SUM(SAL) FROM EMP WHERE DEPT_NO = 0030 AND ENAME LIKE 'SMITH%'; 你可以用DECODE函數高效地得到相同結果 SELECT COUNT(DECODE(DEPT_NO,0020,'X',NULL)) D0020_COUNT, COUNT(DECODE(DEPT_NO,0030,'X',NULL)) D0030_COUNT, SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL, SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL FROM EMP WHERE ENAME LIKE 'SMITH%'; 類似的,DECODE函數也可以運用于GROUP BY 和ORDER BY子句中. 7. 用TRUNCATE替代DELETE 當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復的信息. 如果你沒有COMMIT事務,ORACLE會將數據恢復到刪除之前的狀態(準確地說是恢復到執行刪除命令之前的狀況) 而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的信息.當命令運行后,數據不能被恢復.因此很少的資源被調用,執行時間也會很短. TRUNCATE只在刪除全表或分區適用,TRUNCATE是DDL不是DML8. 用Where子句替換HAVING子句 避免使用HAVING子句, HAVING 只會在檢索出所有。
Oracle語句優化有哪些規則
用EXISTS替換DISTINCT當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT。
一般可以考慮用EXIST替換例如:低效:SELECT DISTINCT DEPT_NO,DEPT_NAMEFROM DEPT D,EMP EWHERE D。 DEPT_NO = E。
DEPT_NO高效:SELECT DEPT_NO,DEPT_NAMEFROM DEPT DWHERE EXISTS ( SELECT 'X'FROM EMP EWHERE E。DEPT_NO = D。
DEPT_NO);EXISTS 使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立刻返回結果。 22。
識別‘低效執行’的SQL語句用下列SQL工具找出低效SQL:SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,SQL_TEXTFROM V$SQLAREAWHERE EXECUTIONS>0AND BUFFER_GETS > 0 AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS 8 ORDER BY 4 DESC;(譯者按: 雖然目前各種關于SQL優化的圖形化工具層出不窮,但是寫出自己的SQL工具來解決問題始終是一個最好的方法)23。 使用TKPROF 工具來查詢SQL性能狀態SQL trace 工具收集正在執行的SQL的性能狀態數據并記錄到一個跟蹤文件中。
這個跟蹤文件提供了許多有用的信息,例如解析次數。執行次數,CPU使用時間等。
這些數據將可以用來優化你的系統。設置SQL TRACE在會話級別: 有效ALTER SESSION SET SQL_TRACE TRUE設置SQL TRACE 在整個數據庫有效仿, 你必須將SQL_TRACE參數在init。
ora中設為TRUE, USER_DUMP_DEST參數說明了生成跟蹤文件的目錄(譯者按: 這一節中,作者并沒有提到TKPROF的用法。
Oracle語句優化53個規則是什么
Oracle sql 性能優化調整1。
選用適合的ORACLE優化器ORACLE的優化器共有3種:a。 RULE (基于規則) b。
COST (基于成本) c。 CHOOSE (選擇性)設置缺省的優化器,可以通過對init。
ora文件中OPTIMIZER_MODE參數的各種聲明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS 。 你當然也在SQL句級或是會話(session)級對其進行覆蓋。
為了使用基于成本的優化器(CBO, Cost-Based Optimizer) , 你必須經常運行analyze 命令,以增加數據庫中的對象統計信息(object statistics)的準確性。 如果數據庫的優化器模式設置為選擇性(CHOOSE),那么實際的優化器模式將和是否運行過analyze命令有關。
如果table已經被analyze過, 優化器模式將自動成為CBO , 反之,數據庫將采用RULE形式的優化器。在缺省情況下,ORACLE采用CHOOSE優化器,為了避免那些不必要的全表掃描(full table scan) , 你必須盡量避免使用CHOOSE優化器,而直接采用基于規則或者基于成本的優化器。
2。 訪問Table的方式ORACLE 采用兩種訪問表中記錄的方式:a。
全表掃描全表掃描就是順序地訪問表中每條記錄。 ORACLE采用一次讀入多個數據塊(database block)的方式優化全表掃描。
b。 通過ROWID訪問表你可以采用基于ROWID的訪問方式情況,提高訪問表的效率, ROWID包含了表中記錄的物理位置信息……ORACLE采用索引(INDEX)實現了數據和存放數據的物理位置(ROWID)之間的聯系。
通常索引提供了快速訪問ROWID的方法,因此那些基于索引列的查詢就可以得到性能上的提高。3。
共享SQL語句為了不重復解析相同的SQL語句,在第一次解析之后, ORACLE將SQL語句存放在內存中。這塊位于系統全局區域SGA(system global area)的共享池(shared buffer pool)中的內存可以被所有的數據庫用戶共享。
因此,當你執行一個SQL語句(有時被稱為一個游標)時,如果它和之前的執行過的語句完全相同, ORACLE就能很快獲得已經被解析的語句以及最好的執行路徑。 ORACLE的這個功能大大地提高了SQL的執行性能并節省了內存的使用。
可惜的是ORACLE只對簡單的表提供高速緩沖(cache buffering) ,這個功能并不適用于多表連接查詢。 數據庫管理員必須在init。
ora中為這個區域設置合適的參數,當這個內存區域越大,就可以保留更多的語句,當然被共享的可能性也就越大了。當你向ORACLE 提交一個SQL語句,ORACLE會首先在這塊內存中查找相同的語句。
這里需要注明的是,ORACLE對兩者采取的是一種嚴格匹配,要達成共享,SQL語句必須完全相同(包括空格,換行等)。 共享的語句必須滿足三個條件:A。
字符級的比較:當前被執行的語句和共享池中的語句必須完全相同。例如:SELECT * FROM EMP;和下列每一個都不同SELECT * from EMP;Select * From Emp;SELECT * FROM EMP;B。
兩個語句所指的對象必須完全相同:例如:用戶 對象名 如何訪問Jack sal_limit private synonym Work_city public synonym Plant_detail public synonym Jill sal_limit private synonym Work_city public synonym Plant_detail table owner考慮一下下列SQL語句能否在這兩個用戶之間共享。 SQL能否共享原因select max(sal_cap) from sal_limit;不能每個用戶都有一個private synonym - sal_limit , 它們是不同的對象select count(*0 from work_city where sdesc like 'NEW%';能兩個用戶訪問相同的對象public synonym - work_city select a。
sdesc,b。location from work_city a , plant_detail b where a。
city_id = b。city_id不能用戶jack 通過private synonym訪問plant_detail 而jill 是表的所有者,對象不同。
C。 兩個SQL語句中必須使用相同的名字的綁定變量(bind variables)例如:第一組的兩個SQL語句是相同的(可以共享),而第二組中的兩個語句是不同的(即使在運行時,賦于不同的綁定變量相同的值)a。
select pin , name from people where pin = :blk1。 pin;select pin , name from people where pin = :blk1。
pin;b。 select pin , name from people where pin = :blk1。
ot_ind;select pin , name from people where pin = :blk1。 ov_ind;。
30個Oracle語句優化規則是哪些
1.選用適合的Oacle優化器 Oacle的優化器共有3種: *(基于規則) .COST(基于成本) *(選擇性) 設置缺省的優化器,可以通過對*文件中OPTIMIZER_MODE參數的各種聲明,如RULE、COST、CHOOSE、ALL_ROWS、FIRST_ROWS。
你當然也在SQL句級或是會話(session)級對其進行覆蓋。 為了使用基于成本的優化器(CBO,Cost-Based Optimize),你必須經常運行analyze命令,以增加數據庫中的對象統計信息(oject statistics)的準確性。
如果數據庫的優化器模式設置為選擇性(CHOOSE),那么實際的優化器模式將和是否運行過analyze命令有關。如果tale已經被analyze過,優化器模式將自動成為CBO,反之,數據庫將采用RULE形式的優化器。
在缺省情況下,Oacle采用CHOOSE優化器,為了避免那些不必要的全表掃描(full tale scan),你必須盡量避免使用CHOOSE優化器,而直接采用基于規則或者基于成本的優化器。 2.訪問Tale的方式Oacle采用兩種訪問表中記錄的方式: a.全表掃描 全表掃描就是順序地訪問表中每條記錄。
Oacle采用一次讀入多個數據塊(dataase lock)的方式優化全表掃描。 . 通過ROWID訪問表 你可以采用基于ROWID的訪問方式情況,提高訪問表的效率,ROWID包含了表中記錄的物理位置信息……Oacle采用索引(INDEX)實現了數據和存放數據的物理位置(ROWID)之間的聯系。
通常索引提供了快速訪問ROWID的方法,因此那些基于索引列的查詢就可以得到性能上的提高。 3.共享SQL語句 為了不重復解析相同的SQL語句,在第一次解析之后,Oacle將SQL語句存放在內存中。
這塊位于系統全局區域SGA(system gloal aea)的共享池(shaed uffe pool)中的內存可以被所有的數據庫用戶共享。因此,當你執行一個SQL語句(有時被稱為一個游標)時,如果它和之前的執行過的語句完全相同,Oacle就能很快獲得已經被解析的語句以及最好的執行路徑。
Oacle的這個功能大大地提高了SQL的執行性能并節省了內存的使用。 可惜的是Oacle只對簡單的表提供高速緩沖(cache uffeing) ,這個功能并不適用于多表連接查詢。
數據庫管理員必須在*中為這個區域設置合適的參數,當這個內存區域越大,就可以保留更多的語句,當然被共享的可能性也就越大了。 當你向Oacle提交一個SQL語句,Oacle會首先在這塊內存中查找相同的語句。
這里需要注明的是,Oacle對兩者采取的是一種嚴格匹配,要達成共享,SQL語句必須完全相同(包括空格,換行等)。 共享的語句必須滿足三個條件: A.字符級的比較: 當前被執行的語句和共享池中的語句必須完全相同。
例如: SELECT * FROM EMP; 和下列每一個都不同 SELECT * fom EMP; Select * Fom Emp; SELECT * FROM EMP; B.兩個語句所指的對象必須完全相同: 例如: 用戶對象名如何訪問 Jack sal_limit pivate synonym Wok_city pulic synonym Plant_detail pulic synonym Jill sal_limit pivate synonym Wok_city pulic synonym Plant_detail tale owne 考慮一下下列SQL語句能否在這兩個用戶之間共享。 SQL能否共享原因 select max(sal_cap) fom sal_limit;不能每個用戶都有一個pivate synonym - sal_limit,它們是不同的對象 select count(*0 fom wok_city whee sdesc like 'NEW%';能兩個用戶訪問相同的對象pulic synonym - wok_city select *,.location fom wok_city a,plant_detail whee *_id = .city_id不能用戶jack通過pivate synonym訪問plant_detail而jill是表的所有者,對象不同。
C.兩個SQL語句中必須使用相同的名字的綁定變量(ind vaiales) 例如:第一組的兩個SQL語句是相同的(可以共享),而第二組中的兩個語句是不同的(即使在運行時,賦于不同的綁定變量相同的值) a. select pin ,name fom people whee pin = :*; select pin ,name fom people whee pin = :*; . select pin ,name fom people whee pin = :*_ind; select pin ,name fom people whee pin = :*_ind; 4.選擇最有效率的表名順序(只在基于規則的優化器中有效) Oacle的解析器按照從右到左的順序處理FROM子句中的表名,因此FROM子句中寫在最后的表(基礎表 diving tale)將被最先處理。在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表。
當Oacle處理多個表時,會運用排序及合并的方式連接它們。首先,掃描第一個表(FROM子句中最后的那個表)并對記錄進行派序,然后掃描第二個表(FROM子句中最后第二個表),最后將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合并。
例如: 表TAB1 16,384 條記錄 表TAB2 1條記錄 選擇TAB2作為基礎表(最好的方法) select count(*) fom ta1,ta2 執行時間0.96秒 選擇TAB2作為基礎表(不佳的方法) select count(*) fom ta2,ta1 執行時間26.09秒 如果有3個以上的表連接查詢,那就需要選擇交叉表(intesection tale)作為基礎表,交叉表是指那個被其他表所引用的表。 例如:EMP表描述了LOCATION表和CATEGORY表的交集。
SELECT * FROM LOCATION L , CATEGORY C, EMP E WHERE E。.。
Oracle語句優化規則詳解內容是什么呢
11。
用TRUNCATE替代DELETE當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復的信息。 如果你沒有COMMIT事務,ORACLE會將數據恢復到刪除之前的狀態(準確地說是恢復到執行刪除命令之前的狀況)而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的信息。
當命令運行后,數據不能被恢復。因此很少的資源被調用,執行時間也會很短。
(譯者按: TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML)12。 盡量多使用COMMIT只要有可能,在程序中盡量多使用COMMIT, 這樣程序的性能得到提高,需求也會因為COMMIT所釋放的資源而減少:COMMIT所釋放的資源:a。
回滾段上用于恢復數據的信息。b。
被程序語句獲得的鎖c。 redo log buffer 中的空間d。
ORACLE為管理上述3種資源中的內部花費(譯者按: 在使用COMMIT時必須要注意到事務的完整性,現實中效率和事務完整性往往是魚和熊掌不可得兼)13。 計算記錄條數和一般的觀點相反, count(*) 比count(1)稍快 , 當然如果可以通過索引檢索,對索引列的計數仍舊是最快的。
例如 COUNT(EMPNO)(譯者按: 在CSDN論壇中,曾經對此有過相當熱烈的討論, 作者的觀點并不十分準確,通過實際的測試,上述三種方法并沒有顯著的性能差別)14。 用Where子句替換HAVING子句避免使用HAVING子句, HAVING 只會在檢索出所有記錄之后才對結果集進行過濾。
這個處理需要排序,總計等操作。 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷。
例如:低效:SELECT REGION,AVG(LOG_SIZE)FROM LOCATIONGROUP BY REGIONHAVING REGION REGION != 'SYDNEY'AND REGION != 'PERTH'高效SELECT REGION,AVG(LOG_SIZE)FROM LOCATIONWHERE REGION REGION != 'SYDNEY'AND REGION != 'PERTH'GROUP BY REGION(譯者按: HAVING 中的條件一般用于對一些集合函數的比較,如COUNT() 等等。 除此而外,一般的條件應該寫在WHERE子句中)15。
減少對表的查詢在含有子查詢的SQL語句中,要特別注意減少對表的查詢。 例如:低效SELECT TAB_NAMEFROM TABLESWHERE TAB_NAME = ( SELECT TAB_NAME FROM TAB_COLUMNSWHERE VERSION = 604)AND DB_VER= ( SELECT DB_VER FROM TAB_COLUMNSWHERE VERSION = 604)高效SELECT TAB_NAMEFROM TABLESWHERE (TAB_NAME,DB_VER)= ( SELECT TAB_NAME,DB_VER) FROM TAB_COLUMNSWHERE VERSION = 604)Update 多個Column 例子:低效:UPDATE EMPSET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)WHERE EMP_DEPT = 0020;高效:UPDATE EMPSET (EMP_CAT, SAL_RANGE)= (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)FROM EMP_CATEGORIES)WHERE EMP_DEPT = 0020; 完成 丟棄。
ORACLE優化SQL語句有什么作用
索引是表的一個概念部分,用來提高檢索數據的效率,Oracle使用了一個復雜的自平衡B-tree結構。
通常,通過索引查詢數據比全表掃描要快。當 Oracle找出執行查詢和Update語句的最好路徑時, Oracle優化器將使用索引。
同樣在聯結多個表時使用索引也能夠提高效率。 另一個使用索引的好處是,他提供了主鍵(primary key)的唯一性驗證。
那些LONG或LONG RAW數據類型, 您能夠索引幾乎任何的列。通常, 在大型表中使用索引特別有效。
當然,您也會發現, 在掃描小表時,使用索引同樣能提高效率。雖然使用索引能得到查詢效率的提高,但是我們也必須注意到他的代價。
索引需要空間來存儲,也需要定期維護, 每當有記錄在表中增減或索引列被修改時, 索引本身也會被修改。這意味著每條記錄的INSERT,DELETE , UPDATE將為此多付出 4、 5次的磁盤I/O 。
因為索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應時間變慢。 定期的重構索引是有必要的: ALTER INDEX REBUILD (18)用EXISTS替換DISTINCT: 當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT。
一般能夠考慮用EXIST替換, EXISTS 使查詢更為迅速,因為RDBMS核心模塊將在子查詢的條件一旦滿足后,立即返回結果。 例子: (低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D。
DEPT_NO = E。DEPT_NO (高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT 'X' FROM EMP E WHERE E。
DEPT_NO = D。DEPT_NO); (19)SQL語句用大寫的;因為Oracle總是先解析SQL語句,把小寫的字母轉換成大寫的再執行。
(20)在Java代碼中盡量少用連接符“+”連接字符串。 (21)避免在索引列上使用NOT通常,我們要避免在索引列上使用NOT, NOT會產生在和在索引列上使用函數相同的影響。
當Oracle“碰到”NOT,他就會停止使用索引轉而執行全表掃描。 (22)避免在索引列上使用計算。
WHERE子句中,假如索引列是函數的一部分。優化器將不使用索引而使用全表掃描。
舉例: 低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000; 高效: SELECT … FROM DEPT WHERE SAL > 25000/12; (23)用>=替代>: 高效:SELECT * FROM EMP WHERE DEPTNO >=4 低效: SELECT * FROM EMP WHERE DEPTNO >3 兩者的區別在于,前者DBMS將直接跳到第一個DEPT等于4的記錄而后者將首先定位到DEPTNO=3的記錄并且向前掃描到第一個DEPT大于3的記錄。 (24)用UNION替換OR (適用于索引列): 通常情況下,用UNION替換WHERE子句中的OR將會起到較好的效果。
對索引列使用OR將造成全表掃描。注意,以上規則只針對多個索引列有效。
假如有column沒有被索引,查詢效率可能會因為您沒有選擇OR而降低。 在下面的例子中,LOC_ID 和REGION上都建有索引。
高效:SELECT LOC_ID 。 LOC_DESC ,REGION FROM LOCATION WHERE LOC_ID = 10 UNION SELECT LOC_ID ,LOC_DESC ,REGION FROM LOCATION WHERE REGION = “MELBOURNE” 低效: SELECT LOC_ID ,LOC_DESC ,REGION FROM LOCATION WHERE LOC_ID = 10 OR REGION = “MELBOURNE”。
Oracle 常用語句開發優化問題
推薦方案:用其它相同功能的操作運算代替,如a<>0 改為 a>0 or a<0a<>;'' 改為 a>;''是可行的···對于大數據量的查詢,你可以在非主屬性上建立一個簡單的非聚集索引測試,比如時間。然后來測試就會發現效果,曾經有一個這樣的測試900W數據。在時間上測試between and 和 a>datetime1 and a<datetime2 與這里的 不等于<>;有異曲同工的感覺。
a<>0和between and 都會繞過索引,但是測試結果是 45秒
而用a>datetime1 and a<datetime2 或者這里說的 a>0 or a<0 會用到索引 結果是1秒還是3秒忘了。
很多優化都要大數據量去測試,常涉及到的包括你組合索引的順序,查詢條件 使用函數會繞索引
比如 where name like '張%' 比 where left(name,1)='張' 快 因為條件這里用了函數。
怎樣優化SQL語句提高效率
我們要做到不但會寫SQL,還要做到寫出性能優良的SQL語句。
(1)選擇最有效率的表名順序(只在基于規則的優化器中有效): Oracle的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最后的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,您必須選擇記錄條數最少的表作為基礎表。 假如有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表。
(2)WHERE子句中的連接順序: Oracle采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些能夠過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。 (3)SELECT子句中避免使用‘*’: Oracle在解析的過程中, 會將‘*’依次轉換成任何的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間。
(4)減少訪問數據庫的次數: Oracle在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變量 , 讀數據塊等。 (5)在SQL*Plus , SQL*Forms和Pro*C中重新配置ARRAYSIZE參數, 能夠增加每次數據庫訪問的檢索數據量 ,建議值為200。
(6)使用DECODE函數來減少處理時間: 使用DECODE函數能夠避免重復掃描相同記錄或重復連接相同的表。 (7)整合簡單,無關聯的數據庫訪問: 假如您有幾個簡單的數據庫查詢語句,您能夠把他們整合到一個查詢中(即使他們之間沒有關系)。
(8)刪除重復記錄: 最高效的刪除重復記錄方法 ( 因為使用了ROWID)例子: DELETE FROM EMP E WHERE E。 ROWID > (SELECT MIN(X。
ROWID) FROM EMP X WHERE X。EMP_NO = E。
EMP_NO); (9)用TRUNCATE替代DELETE: 當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放能夠被恢復的信息。 假如您沒有COMMIT事務,ORACLE會將數據恢復到刪除之前的狀態(準確地說是恢復到執行刪除命令之前的狀況) 而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的信息。
當命令運行后,數據不能被恢復。因此很少的資源被調用,執行時間也會很短。
(TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML)。 以上是我對于這個問題的解答,希望能夠幫到大家。
轉載請注明出處華閱文章網 » oracle語句優化