數據庫性能系列之索引(上)

前言

上一次,我們從優化子查詢的角度,講解了一些簡單的數據庫性能優化方面的知識。通過優化子查詢的順序,包括合理使用IN和EXISTS,可以起到部分查詢的效率提升。

但對于其他大多數場景,如單表記錄很大,或多表級聯查詢包含條件或排序時,子查詢的優化往往起不到決定性的效果。所以從今天開始,我們要逐漸接觸這一部分的主角:索引。這部分內容我會分為上中下三篇進行詳細的講解,上篇會著重于索引的概念,以及基礎的使用方式;中篇會講解索引背后的實現原理,便于理解索引如何發揮作用;下篇會結合一些復雜的SQL場景,來描述索引在實際工作中如何使用。

概述

數據庫中的索引,就像一本書的目錄,它可以幫我們快速定位和查找,從而加快數據查詢的效率。

如果我們不使用索引,那么記錄就必須從表中第一行開始進行逐行掃描,直到找出符合條件的記錄為止,這樣的查詢效率,必然是很低的。那么,索引是不是建立得越多就越好呢?

答案是否定的,因為索引也是一種存儲在數據庫硬盤中的數據結構,會占用一定的空間。而且對于數據的新增、修改和刪除時,數據庫也需要對其相關的索引進行更新,進而降低了整體效率。

索引的類型

了解了索引的基本概念之后,我們還需要知道不同索引的用途。索引從功能邏輯上可以分為四類:普通索引、唯一索引、主鍵索引和全文索引。而在物理實現上可以分為兩類:聚集索引和非聚集索引。下面我們來逐一講解:

1、普通索引:最基礎的索引,沒有任何約束,直接建立即可,用于提升查找的效率。

2、唯一索引:在普通索引的基礎上,加入了數據唯一性的約束,用于檢查數據是否唯一,在同一張數據表中,可以有多個唯一索引。

3、主鍵索引:在唯一索引的基礎上,加入了NOT NULL的特性,在我們給數據庫表設置主鍵時,會自動創建主鍵索引,而根據主鍵的特性,一個表中只能有一個主鍵索引。

4、全文索引:一種特殊的基于標記的索引,由數據庫引擎維護,用于快速查找某個字符出現的位置,較少使用。目前此種查找一般會使用搜索引擎實現,如ES(ElasticSearch)。

5、聚集索引:確定了數據存儲的順序,在物理上是連續存儲的,因此聚集索引在每個表中只能有一個。在默認情況下,數據庫會對主鍵約束自動創建聚集索引,這就是數據表中的行記錄通常按照主鍵排列的原因。

6、非聚集索引:在數據庫中有單獨的空間進行存儲,索引項本身是按照順序存儲的,但是索引指向的內容卻是隨機存儲的。也就是說非聚集索引在工作時,系統會進行兩次查找,第一次會找到索引本身,第二次則根據索引對應的位置找出數據行。非聚集索引不會把索引指向的內容像聚集索引一樣直接放到索引后面,而是維護單獨的索引表,為數據的檢索提供方便。由于實現原理的不同,非聚集索引在每個表中可以有多個。

索引的應用

現在我們來看一下索引使用的實際效果,目前我有一張表T_ORG_USER,其中大約有3000條數據。這時我們需要查詢一條記錄如下:

254e2f477a7227bd076e3e828d644e9c.png

我們可以使用主鍵Id和用戶名分別查詢同一條記錄,然后查看查詢記錄的區別,首先我們使用主鍵Id進行查詢:

SET STATISTICS TIME ON
SELECT * FROM T_ORG_USER WHERE F_USER_ID = 8400

查詢結果如下圖所示,執行時間為0毫秒:

35d8152d7b1e72f831ba3421ba446e26.png

此時,我們再使用用戶名進行查詢,用戶名字段沒有建立索引:

SET STATISTICS TIME ON
SELECT * FROM T_ORG_USER WHERE F_NAME = '24'

查詢結果如下圖所示,執行時間為196毫秒:

5b29b9a1a1fda4b2cbc47b66a3222003.png

從執行時間上,我們可以看出二者有明顯的效率差別,這時我們再對F_NAME字段建立索引:

CREATE INDEX IDX_USERNAME ON T_ORG_USER(F_NAME)

再次查詢,結果如圖所示,執行時間縮短到了5毫秒:

989db543bd570fe4a9a4f084b676edcb.png

從上述三次的執行結果中,我們可以總結出以下兩點:

1、對WHERE條件后的字段進行索引,可以大幅度提高查詢的效率

2、采用聚集索引的查詢效率,比采用非聚集索引的查詢效率略高。在我們上述的例子中,第一次使用主鍵進行查詢,系統會使用聚集索引進行查找,而第三次我們使用非聚集索引進行查找,效率會降低。因此在需要多次查詢的場景下,我們的SQL語句應盡量使用主鍵索引進行查詢。

除了我們之前描述的幾種索引類型之外,索引還可以根據字段個數分為單一索引聯合索引

單一索引是指使用單個列創建的索引,如我們上述的IDX_USERNAME所示,而把多個列組合在一起創建的索引,叫做聯合索引。

創建聯合索引時,我們需要注意字段的順序問題,因為字段(a,b,c)和字段(b,a,c)創建出的聯合索引,在使用時查詢效率可能會不同。

導致這樣的原因是由于聯合索引存在最左匹配原則,也就是說如果我們創建了聯合索引(a,b,c)時,WHERE條件如果為WHERE a = 1 AND b = 2 AND c = 3,則會匹配上聯合索引,如果條件為WHERE b = 2,那么聯合索引會失效,查詢就會走全表掃描的方式去查找。還有一些范圍查找操作也會導致聯合索引失效,如果某一列使用了<,<=,>,>=,between等,那么此列后面的列就無法使用到索引。

總結

今天我們講述了索引的基本概念,索引的類型以及索引的基本使用方式。合理使用索引可以幫助我們提升查詢效率,但索引也存在一些缺點,如單獨占用空間,降低數據庫的寫操作性能等,所以我們在使用索引時需要權衡索引的利與弊。

在實際工作中,我們也要根據查詢的業務邏輯來決定如何建立索引,牢記最左匹配原則,適當對語句進行改寫以便于索引生效,也可以大大提升數據查詢的性能。

好了,今天我們要講的內容到這里就結束了,如果有什么疑問或者啟發,歡迎大家在評論區進行留言。下一期我們會從索引背后的原理:B樹和B+樹的算法實現進行講解,敬請期待!

2f2cc7acdb31ac4c7f6e5a46cc9307b6.png

您的點贊和在看是我創作的最大動力,感謝支持

4adc9577564f5db40df6542a01fae604.jpeg

f58d5f46aae1e057bebd358457ab4381.png

e15140963ecebd32663de35174e3d77e.png

公眾號:wacky的碎碎念

知乎:wacky

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

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

相關文章

題目1023:EXCEL排序---------Case后面的是count,不是C

#include<stdio.h> #include<algorithm> #include<cstring> using namespace std;struct student {char num[10];char name[10];int grade; }s[100002]; int cmp1(student s1,student s2)//case 1 按照學號遞增 {return strcmp(s1.num,s2.num)<0; } int…

【ArcGIS微課1000例】0052:創建地理數據庫注記(標準注記、要素關聯注記、尺寸注記)

本文講述創建地理數據庫注記(標準注記、要素關聯注記、尺寸注記)的方法。 文章目錄 一、創建標準注記二、創建與要素關聯的注記三、創建尺寸注記一、創建標準注記 標準注記不與地理數據庫中的要素關聯。標準注記的一個例子是,地圖上標記某山脈的文字,沒有特定的要索代表該…

Lambda表達式超詳解

目錄 背景 Lambda表達式的用法 函數式接口 Lambda表達式的基本使用 語法精簡 變量捕獲 匿名內部類 匿名內部類中的變量捕獲 Lambda的變量捕獲 Lambda表達式在類集中的使用 Collection接口 List接口 Map接口 總結 背景 Lambda表達式是Java SE 8中的一個重要的新特性.…

用十條命令在一分鐘內檢查Linux服務器性能

這種干活必須要和大家分享的啊。 如果你的Linux服務器突然負載暴增&#xff0c;告警短信快發爆你的手機&#xff0c;如何在最短時間內找出Linux性能問題所在&#xff1f;來看Netflix性能工程團隊的這篇博文&#xff0c;看它們通過十條命令在一分鐘內對機器性能問題進行診斷。 概…

[javaEE] JDBC快速入門

JDBC&#xff1a;Java Data Base Connectivity java數據庫連接 1.組成JDBC的兩個包&#xff1a;主要是接口 java.sql javax.sql 2.相應JDBC的數據庫實現 在tomcat的目錄下面添加mysql-connector-java-5.0.8-bin.jar這個數據庫驅動包 package com.tsh.web;import java.io.IOExce…

【ArcGIS微課1000例】0053:注記(水平、沿直線、跟隨要素、牽引線、彎曲注記)的創建與編輯

文章目錄 一、創建注記1.創建注記要素類2. 水平注記3. 沿直線4. 隨沿要素5. 沿引線6. 彎曲二、修改注記1. 復制粘貼2. 移動注記3. 旋轉注記4. 刪除注記5. 堆疊和取消堆疊6. 向注記添加引線7. 將注記轉換為多部分8. 編輯關聯要素的注記一、創建注記 注記的創建方法參考:【ArcG…

定制.NET 6.0的依賴注入

本章是《定制ASP NET 6.0框架系列文章》的第三篇。在本章&#xff0c;我們將學習ASP.NET Core的依賴項注入&#xff08;DI&#xff09;以及如何自定義它。我們將討論以下主題&#xff1a;使用不同的DI容器探索ConfigureServices方法使用其他的ServiceProviderScrutor簡介技術準…

50 個 Redis 必備知識:基礎知識,架構、調優和監控知識及難點解決

本文包括&#xff1a;30 個 Redis 基礎知識&#xff1b;10個 Redis 架構和運維必懂的知識&#xff1b;Redis 調優、監控知識和10個具體應用難點。 本篇文檔已整理成pdf文檔&#xff0c;需要的同學文末自取 30 個 Redis 基礎知識 1、Redis支持哪幾種數據類型&#xff1f; Str…

【ArcGIS微課1000例】0043:ArcGIS繪制國界線的3種方法

本文講解ArcGIS繪制國界線的3種方法。 文章目錄 1. 直接修改國界線符號2. 緩沖區工具3. 制圖表達1. 直接修改國界線符號 直接修改國界線/省界線的符號。點擊“線要素”出現符號選擇器,點擊【編輯符號】按鈕,編輯成下面右圖的形式。缺點:只能在邊界一側出現緩沖樣式,如下面…

javascript雜記

菜鳥教程   http://www.runoob.com/js/js-tutorial.html 響應鍵盤事件  https://www.cnblogs.com/shihaiming/p/6210655.html 窗口變化  http://www.jb51.net/article/124581.htm div定位1  http://www.divcss5.com/shili/s587.shtml   div定位2  https://www.cnbl…

沒有暑假的Ada 要好好努力咯 C#繼續

嗷嗷嗷啊啊啊啊啊轉載于:https://www.cnblogs.com/AdaLoong/p/5645720.html

C# 獲取系統已安裝的.NET版本

本文經原作者授權以原創方式二次分享&#xff0c;歡迎轉載、分享。原文作者&#xff1a;唐宋元明清原文地址&#xff1a; https://www.cnblogs.com/kybs0/p/16478587.htmlC# 獲取系統已安裝的.NET版本獲取系統已安裝的.NET版本&#xff0c;來確定當前應用可運行的環境。獲取系…

.NET 6 Minimal API 的經驗分享

Minimal API 是 .NET 6 提供的最新功能 &#xff0c; 對比傳統的 ASP.NET Core Web API 方式更加直接 , 你可以用幾行代碼編寫好 REST API 。 沒有了祖傳的 Startup.cs 和 Controller &#xff0c;通過簡單的代碼就可以完成 API 的開發。在第二階段的 .NET 挑戰賽中就以 .NET 6…

JavaWeb之Filter過濾器

原本計劃這一篇來總結JSP&#xff0c;由于JSP的內容比較多&#xff0c;又想著晚上跑跑步減減肥&#xff0c;所以今天先介紹Filter以及它的使用舉例&#xff0c;這樣的話還有些時間可以鍛煉鍛煉。言歸正傳&#xff0c;過濾器從字面理解她的話有攔網、過濾的功能&#xff0c;可以…

【ArcGIS微課1000例】0054:尺寸注記的創建與編輯

尺寸注記要素是一種特殊類型的文本,用于顯示地圖上的長度或距離,可以創建各種形狀的尺寸注記要素,如對齊、簡單對齊、水平線狀、垂直線狀和旋轉線狀等。 文章目錄 一、創建尺寸注記1. 直接創建尺寸注記要素2. 通過已有尺寸注記要素創建二、編輯尺寸注記1. 刪除尺寸注記要素2…

利用python實現批量查詢ip地址歸屬地址

今天需要查詢nginx訪問的客戶端ip是否和調度一樣&#xff01;先是用shell把文件中的ip截取出來&#xff1a; python腳本如下&#xff1a;&#xff08;哈哈&#xff0c;新手寫的很草率&#xff09;#!/usr/bin/env#-- coding: utf-8 - import jsonimport urllibimport socketimpo…

Cobbler部署之FAQ處理

Cobbler報錯處理 通過cobbler check檢查出現的報錯 紅色標注為報錯關鍵信息 9.1 報錯一 # cobbler check httpd does not appear to be running and proxying cobbler, or SELinux is in the way. Original traceback: Traceback (most recent call last): File "/usr…

基于.NetCore開發博客項目 StarBlog - (16) 一些新功能 (監控/統計/配置/初始化)

系列文章基于.NetCore開發博客項目 StarBlog - (1) 為什么需要自己寫一個博客&#xff1f;基于.NetCore開發博客項目 StarBlog - (2) 環境準備和創建項目基于.NetCore開發博客項目 StarBlog - (3) 模型設計基于.NetCore開發博客項目 StarBlog - (4) markdown博客批量導入基于.N…

堪比JMeter的.Net壓測工具 - Crank 入門篇

1. 前言 Crank 是.NET 團隊用來運行基準測試的基準測試基礎架構&#xff0c;包括&#xff08;但不限于&#xff09;來自TechEmpower Web 框架基準測試的場景,是2021年.NET Conf 大會上介紹的一項新的項目&#xff0c;其前身是Benchmarks。 Crank目標之一是為開發人員提供一種工…