Oracle 建立索引及SQL優化

来源:https://www.cnblogs.com/afuu/archive/2020/05/19/12917755.html
-Advertisement-
Play Games

資料庫索引: 索引有單列索引複合索引之說 如何某表的某個欄位有主鍵約束和唯一性約束,則Oracle 則會自動在相應的約束列上建議唯一索引。資料庫索引主要進行提高訪問速度。 建設原則: 1、索引應該經常建在Where 子句經常用到的列上。如果某個大表經常使用某個欄位進行查詢,並且檢索行數小於總表行數的 ...


資料庫索引:

索引有單列索引
複合索引之說


如何某表的某個欄位有主鍵約束和唯一性約束,則Oracle 則會自動在相應的約束列上建議唯一索引。資料庫索引主要進行提高訪問速度。

建設原則:

 1、索引應該經常建在Where 子句經常用到的列上。如果某個大表經常使用某個欄位進行查詢,並且檢索行數小於總表行數的5%。則應該考慮。

 2、對於兩表連接的欄位,應該建立索引。如果經常在某表的一個欄位進行Order By 則也經過進行索引。

 3、不應該在小表上建設索引。

優缺點:
 1、索引主要進行提高數據的查詢速度。 當進行DML時,會更新索引。因此索引越多,則DML越慢,其需要維護索引。 因此在創建索引及DML需要權衡。

創建索引:
 單一索引:Create Index <Index-Name> On <Table_Name>(Column_Name);

 複合索引: Create Index i_deptno_job on emp(deptno,job); —>在emp表的deptno、job列建立索引。

  select * from emp where deptno=66 and job='sals' ->走索引。

  select * from emp where deptno=66 OR job='sals' ->將進行全表掃描。不走索引

  select * from emp where deptno=66 ->走索引。

  select * from emp where job='sals' ->進行全表掃描、不走索引。

  如果在where 子句中有OR 操作符或單獨引用Job 列(索引列的後面列) 則將不會走索引,將會進行全表掃描。

 


Sql 優化:

當Oracle資料庫拿到SQL語句時,其會根據查詢優化器分析該語句,並根據分析結果生成查詢執行計劃。
也就是說,資料庫是執行的查詢計劃,而不是Sql語句。
查詢優化器有rule-based-optimizer(基於規則的查詢優化器) 和Cost-Based-optimizer(基於成本的查詢優化器)。
其中基於規則的查詢優化器在10g版本中消失。
對於規則查詢,其最後查詢的是全表掃描。而CBO則會根據統計信息進行最後的選擇。


1、先執行From ->Where ->Group By->Order By

2、執行From 字句是從右往左進行執行。因此必須選擇記錄條數最少的表放在右邊。這是為什麼呢?  

3、對於Where字句其執行順序是從後向前執行、因此可以過濾最大數量記錄的條件必須寫在Where子句的末尾,而對於多表之間的連接,則寫在之前。
因為這樣進行連接時,可以去掉大多不重覆的項。  

4. SELECT子句中避免使用(*)ORACLE在解析的過程中, 會將’*’ 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間

5、索引失效的情況:
 ① Not Null/Null 如果某列建立索引,當進行Select * from emp where depto is not null/is null。 則會是索引失效。
 ② 索引列上不要使用函數,SELECT Col FROM tbl WHERE substr(name ,1 ,3 ) = 'ABC' 
或者SELECT Col FROM tbl WHERE name LIKE '%ABC%' 而SELECT Col FROM tbl WHERE name LIKE 'ABC%' 會使用索引。

 ③ 索引列上不能進行計算SELECT Col FROM tbl WHERE col / 10 > 10 則會使索引失效,應該改成
SELECT Col FROM tbl WHERE col > 10 * 10

 ④ 索引列上不要使用NOT ( != 、 <> )如:SELECT Col FROM tbl WHERE col ! = 10 
應該 改成:SELECT Col FROM tbl WHERE col > 10 OR col < 10 。

6、用UNION替換OR(適用於索引列)
  union:是將兩個查詢的結果集進行追加在一起,它不會引起列的變化。 由於是追加操作,需要兩個結果集的列數應該是相關的,
並且相應列的數據類型也應該相當的。union 返回兩個結果集,同時將兩個結果集重覆的項進行消除。 如果不進行消除,用UNOIN ALL.

通常情況下, 用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”
  如果你堅持要用OR, 那就需要返回記錄最少的索引列寫在最前面.

7. 用EXISTS替代IN、用NOT EXISTS替代NOT IN
在許多基於基礎表的查詢中, 為了滿足一個條件, 往往需要對另一個表進行聯接. 在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率. 
在子查詢中, NOT IN子句將執行一個內部的排序和合併. 無論在哪種情況下, NOT IN都是最低效的(因為它對子查詢中的表執行了一個全表遍歷). 
為了避免使用NOT IN, 我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS.

例子:

高效: SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)

低效: SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 資料庫 1.1 資料庫基礎 1.1.1 選擇 1.1.1.1 Having 子句的作用是(C )。 A.查詢結果的分組條件 B.組的篩選條件 C.限定返回的行的判斷條件 D.對結果集進行排序 1.1.1.2 最常用的一種基本數據模型是關係數據模型,它的表示採用(D) A.樹 B.網路 C.圖 D.二 ...
  • 在Oracle和SQL Server資料庫中,可以設置一些複雜的賬號密碼策略,例如在失敗登錄超過N次即可鎖定賬號,那麼在MySQL中能否也有這樣的功能呢?答案是MySQL也有類似這樣的功能,只不過在MySQL中是在其登錄失敗超過閥值後,延遲響應時間,而不是鎖定賬號,在MySQL 5.7.17 以後提... ...
  •  JDBC基本使用方法 JDBC固定步驟: 載入驅動 連接資料庫,代表資料庫 向資料庫發送SQL的對象Statement: CRUD 編寫SQL (根據業務, 不同的SQL) 執行SQL 遍歷結果集 關閉連接 補充: statement.executeQuery(); //執行查詢操作 state ...
  • Redis伺服器負責與多個客戶端建立網路通信,處理客戶端發送的命令請求,在資料庫中保存客戶端執行命令所產生的數據,並通過資源管理來維持伺服器自身的運轉。 命令請求過程(以set命令為例) 1、客戶端向伺服器發送命令請求 SET KEY VALUE。 Redis伺服器的命令請求來自於Redis客戶端, ...
  • 數據中台、相信這四個字大家一定不陌生。因為在2019年、數據中台可謂是最火的概念之一,很多大公司都在佈局自己的數據中台。 那麼數據中台到底是什麼?它和我們熟知的數據平臺有啥區別?它為什麼會這麼火、能給企業帶來什麼價值呢?數據中台整體架構和全景圖又是什麼呢? 筆者有幸參與了公司數據中台從0到N的建設, ...
  • 今天導一些數據從Excel中至Sqlserver 資料庫中,在做數據合併去重的時候發現,有兩條數據一模一樣,竟然沒有進行合併; 最後發現有一條後面有個“空格”,正是因為這個“空格”讓我抓狂許久,因為它是個假“空格”! 普通的空格移除方法: SELECT ltrim(' 移除掉左邊的空格 ') SEL ...
  • utf8mb4是4個位元組。utf8是3個位元組。utf8mb4相容性更好,占用空間更大。 主要從排序準確性和性能兩方面看: 準確性utf8mb4_unicode_ci 是基於標準的Unicode來排序和比較,能夠在各種語言之間精確排序utf8mb4_general_ci 沒有實現Unicode排序規則 ...
  • --ORACLE表被鎖原因:具體操作某一個FORM界面,或者後臺資料庫操作某一個表時發現一直出於"假死"狀態, --可能是該表被某一用戶鎖定,導致其他用戶無法繼續操作 --查詢被鎖的表 select b.owner, b.object_name, a.session_id, a.locked_mod ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...