[數據庫之十一] 數據庫索引之聯合索引

??執行數據庫查詢時,通常查詢條件是多對個屬性進行判斷和約束,對于這種類型的查詢,如果存在多個索引則使用多個索引,或者使用建立在多屬性搜索碼上的索引,這樣能提高查詢效率。

一、使用多個單碼索引

??假設數據表 instructor 有兩個單碼索引,分別建立在 dept_namesalary 上。為了找到金融系中工資為 80000 的所有老師,使用以下 SQL:

select ID
from   instructor
where  dept_name = "Finance" and salary = 80000;



??可以使用以下幾種查詢策略:

1、使用 dept_name 上的索引,找出屬于金融系的所有記錄,再檢查每條記錄是否滿足 salary = 80000。
2、使用 salary 上的索引,找出所有工資為 80000 的記錄,再檢查每條記錄是否滿足 dept_name = "Finance"。
3、利用 dept_name 上的索引找出指向屬于金融系的記錄的所有指針。同樣利用 salary 上的索引找出指向工資等于 80000 的記錄的所有指針。兩個指針集合的交集,即為所有滿足查詢條件的記錄的所有指針。


??三種策略只有第三種利用了存在的多種索引的優勢,但是在以下條件下也可能是糟糕的選擇:

  • 屬于金融系的記錄太多

  • 工資為 80000 的記錄太多

  • 屬于金融系且工資為 80000 的記錄只有幾個



    因為為了得到一個很小的結果集,必須掃描大量指針,策略的執行效果取決于索引屬性值的分布。


二、多碼索引(聯合索引)

1、最左前綴匹配規則

??為了解決上面的問題,一個可行的方案是在復合的搜索碼(dept_name, salary)上建立和使用索引,這就是聯合索引

??聯合索引有個規則,叫最左前綴匹配規則,即 SQL 語句中用到了聯合索引中的最左邊的索引,那么這條 SQL 語句就可以利用這個聯合索引去進行匹配,值得注意的是,當遇到范圍查詢(>、<、between、like)就會停止匹配。



??比如對于SQL:

select ID
from   instructor
where  dept_name = "Finance" and salary = 80000;select ID
from   instructor
where  dept_name = "Finance";

??都是可以匹配索引的,查詢條件一個是(dept_name, salary),一個是(dept_name),復合最左前綴匹配規則。


??但是對下面的查詢是不匹配的:

where  salary = 80000;

??因為前面的查詢條件沒有 dept_name,聯合索引最左邊的屬性 dept_name 沒有匹配到,就不會對后面的屬性 salary 使用索引。


??對下面的查詢也是可以匹配到索引的

where salary = 80000 and dept_name = "Finance";

??因為數據庫有優化器會自動調整 salary、dept_name 的順序與索引順序一致。


??遇到范圍查詢,會停止對后面屬性的索引匹配,比如建立索引(a, b, c, d),where 后條件為

a = 1 and b = 2 and c > 3 and d = 4

??那么,a,b,c三個字段能用到索引,而d就匹配不到。因為遇到了范圍查詢,但是如果把索引改成(a, b, d, c)則又可以匹配了,因為數據庫優化器會自動把查詢條件的屬性順序調整為

a = 1 and b = 2 and d = 4 and c > 3



2、數據結構

假設,我們對(a,b)字段建立索引,那么入下圖所示

對于聯合索引(a, b),先按 a 進行排序,相同的 a 內部才按 b 進行排序,對于整個 B+ 樹來說,a 在其中是有序的,按照前序遍歷的順序,上圖中各個樹節點 a 的值分別為 1, 1, 2, 2, 2, 3, 3。

而 b 是一種全局無需,局部有序的狀態,即相同的 a 內部的有序。同樣按照前序遍歷的順序,各個結點 b 的值分別為 1, 2, 1, 4, 4, 1, 2。因此對于 b = 2 這種查詢條件是沒辦法使用索引的。

只有當 a 的值確定時,b 才是有序的。比如 a = 1 時,b 值是 1, 2 的有序狀態;當 a = 2 時,b 值是 1, 4 的有序狀態。因此,執行 a = 1 and b = 2 時 a, b 字段能用到索引,而執行 a > 1 and b = 2 時,a 字段能用到索引,b 字段用不到索引,因此此時 a 的值是一個范圍,不是固定的,在這個范圍內 b 值不是有序的,因此 b 字段用不上索引。

所以,根據最左前綴匹配原則,在遇到范圍查詢時,就會停止匹配。



3、實戰
題型一

如果sql為

SELECT * FROM table WHERE a = 1 and b = 2 and c = 3;

如何建立索引?

如果此題回答為對(a,b,c)建立索引,那都可以回去等通知了。 此題正確答法是,(a,b,c)或者(c,b,a)或者(b,a,c)都可以,重點要的是將區分度高的字段放在前面,區分度低的字段放后面。像性別、狀態這種字段區分度就很低,我們一般放后面。

例如假設區分度由大到小為b,a,c。那么我們就對(b,a,c)建立索引。在執行sql的時候,優化器會 幫我們調整where后a,b,c的順序,讓我們用上索引。


題型二

如果sql為

SELECT * FROM table WHERE a > 1 and b = 2;

如何建立索引?

如果此題回答為對(a,b)建立索引,那都可以回去等通知了。 此題正確答法是,對(b,a)建立索引。如果你建立的是(a,b)索引,那么只有a字段能用得上索引,畢竟最左匹配原則遇到范圍查詢就停止匹配。 如果對(b,a)建立索引那么兩個字段都能用上,優化器會幫我們調整where后a,b的順序,讓我們用上索引。


題型三

如果sql為

SELECT * FROM `table` WHERE a > 1 and b = 2 and c > 3;

如何建立索引? 此題回答也是不一定,(b,a)或者(b,c)都可以,要結合具體情況具體分析。

拓展一下

SELECT * FROM `table` WHERE a = 1 and b = 2 and c > 3;

怎么建索引?嗯,大家一定都懂了!

(a, b, c) 或 (b, a, c) 根據區分度決定 a 前還是 b 前。


題型四
SELECT * FROM `table` WHERE a = 1 ORDER BY b;

如何建立索引? 這還需要想?一看就是對(a,b)建索引,當a = 1的時候,b相對有序,可以避免再次排序! 那么

SELECT * FROM `table` WHERE a > 1 ORDER BY b;

如何建立索引? 對(a)建立索引,因為a的值是一個范圍,這個范圍內b值是無序的,沒有必要對(a,b)建立索引。

拓展一下

SELECT * FROM `table` WHERE a = 1 AND b = 2 AND c > 3 ORDER BY c;

怎么建索引?

(a, b, c) 或 (b, a, c) 根據區分度決定 a 前還是 b 前。


題型五
SELECT * FROM `table` WHERE a IN (1,2,3) and b > 1;

如何建立索引?

還是對(a,b)建立索引,因為IN在這里可以視為等值引用,不會中止索引匹配,所以還是(a,b)!



喜歡的朋友記得點贊、收藏、關注哦!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79201.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79201.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79201.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

增強學習(Reinforcement Learning)簡介

增強學習&#xff08;Reinforcement Learning&#xff09;簡介 增強學習是機器學習的一種范式&#xff0c;其核心目標是讓智能體&#xff08;Agent&#xff09;通過與環境的交互&#xff0c;基于試錯機制和延遲獎勵反饋&#xff0c;學習如何選擇最優動作以最大化長期累積回報。…

PaddlePaddle 和PyTorch選擇與對比互斥

你遇到的錯誤信息如下&#xff1a; RuntimeError: (PreconditionNotMet) Tensors dimension is out of bound.Tensors dimension must be equal or less than the size of its memory.But received Tensors dimension is 8, memorys size is 0.[Hint: Expected numel() * Size…

vison transformer vit 論文閱讀

An Image is Worth 16x16 Words 20年的論文看成10年的哈斯我了 [2010.11929] 一張圖像勝過 16x16 個單詞&#xff1a;用于大規模圖像識別的轉換器 --- [2010.11929] An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 為什么transformer好訓練&am…

依賴關系-根據依賴關系求候選碼

關系模式R&#xff08;U, F&#xff09;, U{}&#xff0c;F是R的函數依賴集&#xff0c;可以將屬性分為4類&#xff1a; L: 僅出現在依賴集F左側的屬性 R: 僅出現在依賴集F右側的屬性 LR: 在依賴集F左右側都出現的屬性 NLR: 在依賴集F左右側都未出現的屬性 結論1: 若X是L類…

SAP note 3565626 : Baltimore CyberTrust 根證書即將過期

SAP note 3565626 &#xff1a; Baltimore CyberTrust 根證書即將過期 20250512 2025年5月9日 癥狀 您已收到來? SAP Integration Suite/Cloud Integration 服務的通知郵件&#xff0c; 建議 Baltimore CyberTrust 根證書將于 2025 年 5 ? 12 ? 過期&#xff0c;其中 Balt…

算法精講:字母異位詞分組問題剖析

算法精講:字母異位詞分組問題剖析 一、引言 在算法的學習與實踐中,字符串相關的問題一直是重點和難點。今天我們要深入探討的“字母異位詞分組”問題,不僅考驗對字符串操作的理解,還涉及到數據結構的巧妙運用。通過解決這個問題,我們能進一步提升算法思維和代碼實現能力。…

【每日八股】復習 Redis Day7:應知應會的 33 條 Redis 基礎八股文

應知應會的 33 條 Redis 基礎八股文 今天對 Redis 八股文進行收官總結&#xff0c;共收錄了 33 條基礎八股文。 文章目錄 應知應會的 33 條 Redis 基礎八股文Redis 持久化簡述 Redis 持久化的兩種策略&#xff1f;AOF 的三種持久化策略&#xff1f;AOF 磁盤重寫機制&#xf…

k8s之探針

探針介紹&#xff1a; 編排工具運行時&#xff0c;雖說pod掛掉會在控制器的調度下會重啟&#xff0c;出現pod重啟的時候&#xff0c;但是pod狀態是running,無法真實的反應當時pod健康狀態&#xff0c;我們可以通過Kubernetes的探針監控到pod的實時狀態。 Kubernetes三種探針類…

記9(Torch

目錄 1、Troch 1、Troch 函數說明舉例torch.tensor()torch.arange()創建張量創建一個標量&#xff1a;torch.tensor(42)創建一個一維張量&#xff1a;torch.tensor([1, 2, 3])創建一個二維張量&#xff1a;torch.tensor([[1, 2], [3, 4]])生成一維等差張量&#xff1a;語法&am…

flask開啟https服務支持

目錄 一、背景 二、開啟https支持 三、自簽名 1、安裝openssl 2、驗證安裝 3、自簽名 四、編寫代碼 五、訪問https接口 一、背景 最近在做自動化業務&#xff0c;需要兼容現在主流的框架開發的前端頁面&#xff0c;于是到github找到了幾個項目&#xff0c;clone下來項目并…

路由交換實驗

案例一&#xff1a;實施和配置RIPV2 1.給AR1配置接口 查看R1接口配置情況 2.配置三臺路由的RIP協議&#xff0c;版本為version2 &#xff0c;關閉自動匯總&#xff0c;通告所有的直連接口 案例二&#xff1a;配置多區域的OSPF協議 1.配置R1的接口IP地址參數 2.配置r2,r3的接口參…

北斗導航 | RTKLib中重難點技術,公式,代碼

Rtklib 一、抗差自適應卡爾曼濾波1. **核心難點**2. **公式與代碼實現**二、模糊度固定與LAMBDA算法1. **核心難點**2. **LAMBDA算法實現**3. **部分模糊度固定技術**三、偽距單點定位與誤差修正1. **多系統多頻點修正**2. **接收機鐘差與系統間偏差**四、動態模型與周跳處理1.…

RT-Thread 深入系列 Part 2:RT-Thread 內核核心機制深度剖析

摘要: 本文從線程管理、調度器原理、中斷處理與上下文切換、IPC 同步機制、內存管理五大核心模塊出發,深入剖析 RT-Thread 內核實現細節,并輔以源碼解讀、流程圖、時序圖與性能數據。 目錄 線程管理與調度器原理 1.1 線程控制塊(TCB)結構 1.2 就緒隊列與優先級調度 1.3 時…

STM32部分:3、STM32CubeMX 工程創建

飛書文檔https://x509p6c8to.feishu.cn/wiki/LfMpwjktZiMAuMkayt6c0LGZnpx 1、打開STM32CUBEMX&#xff0c;選擇File->New Project 如果首次使用&#xff0c;可能會自動下載一些依賴包&#xff0c;可以等待下載完成。 2、選擇對應芯片 MCU/MPU Selector->輸入“STM32F1…

第十五章,SSL VPN

前言 IPSec 和 SSL 對比 IPSec遠程接入場景---client提前安裝軟件&#xff0c;存在一定的兼容性問題 IPSec協議只能夠對感興趣的流量進行加密保護&#xff0c;意味著接入用戶需要不停的調整策略&#xff0c;來適應IPSec隧道 IPSec協議對用戶訪問權限顆粒度劃分的不夠詳細&…

深度學習系統學習系列【4】之反向傳播(BP)四個基本公式推導

文章目錄 補充知識&#xff1a;? 和 ⊙ 運算符詳解? (nabla) 運算符⊙ (圓圈點) 運算符 反向傳播基本公式計算圖和基本定義BP1&#xff1a;輸出層誤差推導BP1公式的重要性實際例子BP2第 l l l層誤差推導BP3 &#xff1a;損失函數關于偏置(b)偏導的推導BP4&#xff1a; 損失函…

極狐Gitlab 如何創建并使用子群組?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 子群組 (BASIC ALL) 您可以將極狐GitLab 群組組織成子群組。您可以使用子群組&#xff1a; 內部和外部組織分開。因為每個子…

HarmonyOS基本的應用的配置

鴻蒙HarmonyOS組建頁面 1、創建ets文件并配置2、修改main_pages.json文件3、修改EntryAbility.ets文件&#xff08;啟動時加載的頁面&#xff09; 1、創建ets文件并配置 Index.ets是創建項目自動構建生成的&#xff0c;我們可以將其刪除掉&#xff0c;并重新在page文件夾下創建…

強化學習三大基本方法-DP、MC、TD

強化學習進階 本文主要講解 動態規劃法&#xff08;Dynamic Programming DP&#xff09;蒙特卡洛法&#xff08;Monte Carlo MC&#xff09;時序差分法&#xff08;Temporal Difference TD&#xff09; 1. 動態規劃法 1.1 動態規劃概念 動態規劃核心思想&#xff1a; 其核心…

《Spring Boot 3.0全新特性詳解與實戰案例》

大家好呀&#xff01;今天讓我們輕松掌握Spring Boot 3.0的所有新特性&#xff01;&#x1f680; &#x1f4cc; 第一章&#xff1a;Spring Boot 3.0簡介 1.1 什么是Spring Boot 3.0&#xff1f; Spring Boot 3.0就像是Java開發者的"超級工具箱"&#x1f9f0;&…