亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MySql索引原理和SQL優(yōu)化方式

 更新時間:2024年09月23日 14:34:05   作者:小辛學西嘎嘎  
索引是提升數(shù)據(jù)庫查詢效率的有序存儲結(jié)構(gòu),包括主鍵索引、唯一索引、普通索引等,約束則用于數(shù)據(jù)完整性,包含主鍵、唯一、外鍵等約束,B+樹是常用的索引結(jié)構(gòu),減少磁盤IO次數(shù),索引應(yīng)用場景包括where、groupby、orderby

一、索引與約束

1、索引是什么

索引是一種有序的存儲結(jié)構(gòu),它按照單個或者多個列的值進行排序。

并且它分為:主鍵索引、唯一索引、普通索引、組合索引、以及全文索引。

我們使用索引的目的就是為了提升搜索的效率。

2、索引的分類

列的屬性-索引約束

  • 主鍵索引:非空唯一索引,一個表只有一個主鍵索引;在 innodb 中,主鍵索引的 B+ 樹包含表數(shù)據(jù)信息;
  • 唯一索引:不可以出現(xiàn)相同的值,可以有 NULL 值;
  • 普通索引:允許出現(xiàn)相同的索引內(nèi)容;
  • 組合索引:對表上的多個列進行索引;
  • 全文索引:將存儲在數(shù)據(jù)庫當中的整本書和整篇文章中的任意內(nèi)容信息查找出來的技術(shù);關(guān)鍵詞 FULLTEXT; 在短字符串中用 LIKE % ;在全文索引中用 match 和 against ;
-- 主鍵索引
PRIMARY KEY(key1, key2)

--唯一索引
UNIQUE(key)

--普通索引
INDEX(key)
-- OR
KEY(key[,...])

--組合索引
INDEX idx(key1,key2[,...]);
UNIQUE(key1,key2[,...]);
PRIMARY KEY(key1,key2[,...]);

約束:為了實現(xiàn)數(shù)據(jù)的完整性,對于 innodb,提供了以下幾種約束,primary key,unique key,foreign key,default,not null;

其中外鍵約束:用來關(guān)聯(lián)兩個表,來保證參照完整性;MyISAM 存儲引擎本身并不支持外鍵,只起到注釋作 用;而 innodb 完整支持外鍵,并具備事務(wù)性;

創(chuàng)建主鍵索引或者唯一索引的時候同時創(chuàng)建了相應(yīng)的約束;但是約束時邏輯上的概念;索引是一個數(shù)據(jù)結(jié)構(gòu)既包含邏輯的概念也包含物理的存儲方式;

數(shù)據(jù)結(jié)構(gòu)

索引包括多種數(shù)據(jù)結(jié)構(gòu),其中最常用的就是B+數(shù)索引,hash索引,全文索引。我們本文主要討論的是在InnoDB引擎中所使用的B+數(shù)索引。那么為什么我們不使用紅黑樹呢?

首先B+樹全稱:多路平衡搜索樹。對于瘦高的紅黑樹來說B+樹是胖矮的。我們把所有的數(shù)據(jù)存放在葉子節(jié)點中,而且葉子節(jié)點還串聯(lián)在一起,一個頁中可以存放幾個葉子節(jié)點,而非葉子節(jié)點存放索引內(nèi)容,并且也放在頁中,我們可以看下圖。

當我們查找一個數(shù)據(jù)的時候,可以使用更少的磁盤IO就可以獲得想要的數(shù)據(jù)。比如我們想要查找25這個節(jié)點的數(shù)據(jù),先查找第一個頁,找到25的位置,在看第二個頁,,在找到第一個葉子節(jié)點,然后平移過去找到25這個節(jié)點,一共有4次磁盤IO(每次查找頁就是一次IO)。

但是使用的是紅黑樹的話,那么就不止4次的磁盤IO了。當然除了更少的磁盤IO后,也是為了方便范圍查找。對于B+樹來說,他的葉子節(jié)點都串聯(lián)在一起,當找到第一個節(jié)點之后,就可以相繼找出其他節(jié)點。但是紅黑樹來說的話,每次都要重新查找葉子節(jié)點。

總結(jié):可以減少磁盤訪問次數(shù);用來組織磁盤數(shù)據(jù),以頁為單位,物理磁盤頁一般為 4K,innodb 默認頁大小為 16K;對頁的訪問是一次磁盤 IO,緩存中會緩存常訪問的頁; 平衡二叉樹(紅黑樹、AVL 樹) 特征:非葉子節(jié)點只存儲索引信息,葉子節(jié)點存儲具體數(shù)據(jù)信息;葉子節(jié)點之間互相連接,方便范圍查詢; 每個索引對應(yīng)著一個 B+ 樹;

索引實現(xiàn)-物理存儲

innodb 由段、區(qū)、頁組成;段分為數(shù)據(jù)段、索引段、回滾段等;區(qū)大小為 1 MB(一個區(qū)由 64 個 連續(xù)頁構(gòu)成);頁的默認值為 16k;頁為邏輯頁,磁盤物理頁大小一般為 4K 或者 8K;為了保證區(qū)中的頁連續(xù),存儲引擎一般一次從磁盤中申請 4~5 個區(qū);

3、使用索引的場景

我們每次搜索數(shù)據(jù)都是通過索引來實現(xiàn)的,其中在哪里可以使用到索引呢?是在where,group by,order by后面使用索引的。那么哪些場景不適合使用索引呢?首先就是沒有where,group by,order by的地方,還有區(qū)分度不高的列,需要經(jīng)常修改的列,表數(shù)據(jù)量少。

我們創(chuàng)建B+樹類型的索引就是為了通過比較來找到我們所需要的數(shù)據(jù),但是當區(qū)分度不高的時候,反而會降低速度,如果經(jīng)常修改這個列,那么我們的B+的結(jié)構(gòu)就要經(jīng)常變化,更加影響速率,表的數(shù)據(jù)較少的時候,沒有必要去創(chuàng)建索引,創(chuàng)建索引反而會浪費空間。

學習了上面所講述的B+樹和索引之后來想一下下面幾個經(jīng)典的面試題吧:

  • 為什么采用多路的樹結(jié)構(gòu)?一個節(jié)點有多條鏈路,相較于平衡二叉搜索樹是一個更加矮胖的結(jié)構(gòu),樹的高度更低,可以較少的磁盤io次數(shù)來索引數(shù)據(jù)。
  • 為什么非葉子節(jié)點只存儲索引信息?B+樹節(jié)點映射固定的大小磁盤數(shù)據(jù),可以包含更多的索引信息。能快速鎖定數(shù)據(jù)所在葉子節(jié)點的位置。
  • 為什么葉子節(jié)點依次相連?便于范圍查詢,避免中序遍歷回溯回去查找下一個節(jié)點。

二、索引方式

1、聚集索引

按照主鍵構(gòu)造的 B+ 樹,葉子節(jié)點中存放數(shù)據(jù)頁中,數(shù)據(jù)也是索引的一部分。

一般來說主鍵索引就可以作為聚集索引,當沒有主鍵的時候,如果有唯一索引,那唯一索引也可以作為聚集索引。18

-- user表中 有id主鍵
select * from user where id >= 18 and id < 40;

我們通過上面的SQL語句,進行主鍵索引(聚集索引),從結(jié)構(gòu)中查找18的位置,然后一層一層找,最后在葉子節(jié)點中找到,然后18到40的位置是連續(xù)的,我們節(jié)點的查找也是順序的。并且這里的葉子節(jié)點,全部都是保存的數(shù)據(jù)。

2、輔助索引(二級索引)

葉子節(jié)點不包含行記錄的全部數(shù)據(jù),輔助索引的葉子節(jié)點中,除了用來排序的 key 還包含一個 bookmark ,該書簽存儲了聚集索引的 key;

-- user表 包含 id name lockyNum; id是主鍵,lockyNum 輔助索引;
select * from user where lockyNum = 33;

由于這里使用的是輔助索引,在輔助索引中,葉子節(jié)點中存儲的并不是數(shù)據(jù),而是主鍵的id,當我們通過輔助索引找到相應(yīng)的位置之后,根據(jù)查找到的主鍵id,再進入聚集索引中,然后操作就是上面聚集索引的過程了。后面簡稱回表查詢。

3、覆蓋索引

從輔助索引中就能找到數(shù)據(jù),而不需通過聚集索引查找;利用輔助索引樹高度一般低于聚集索引 樹;較少磁盤 IO;在實際中我們select后一定不要*,而是具體的寫出想要查找什么字段。

4、最左匹配規(guī)則

對于組合索引,從左到右依次匹配,遇到 > < between like 就停止匹配;在下面的索引中,是組合索引,當我們使用id,name,age;id,name;id;這三種方式去索引的話,就可以走索引結(jié)構(gòu),但是一旦前面沒有id之后,那么就不會走索引結(jié)構(gòu)。也就是說,最左匹配規(guī)則,必須要按著從左往右的順序來。

KEY(id,name,age)

5、索引下推

為了減少回表次數(shù),提升查詢效率;在 MySQL 5.6 的版本開始推出; MySQL 架構(gòu)分為 server 層和存儲引擎層; 沒有索引下推機制之前,server 層向存儲引擎層請求數(shù)據(jù),在 server 層根據(jù)索引條件判斷進行數(shù)據(jù) 過濾; 有索引下推機制之后,將部分索引條件判斷下推到存儲引擎中過濾數(shù)據(jù);最終由存儲引擎將數(shù)據(jù)匯 總返回給 server 層;

三、索引的失效和原則

1、索引失效

  • 1、select ... where A and B 若 A 和 B 中有一個不包含索引,則索引失效;
  • 2、索引字段參與運算,則索引失效;例如: from_unixtime(idx) = '2021-04-30'; 改成 idx = unix_timestamp("2021-04-30")
  • 3、索引字段發(fā)生隱式轉(zhuǎn)換,則索引失效;例如:將列隱式轉(zhuǎn)換為某個類型,實際等價于在索引列上作 用了隱式轉(zhuǎn)換函數(shù);
  • 4、LIKE 模糊查詢,通配符 % 開頭,則索引失效;例如: select * from user where name like '%Mark';
  • 5、在索引字段上使用 NOT <> != 索引失效;如果判斷 id <> 0 則修改為 idx > 0 or idx < 0 ;
  • 6、組合索引中,沒使用第一列索引,索引失效;

2、索引原則

  • 1、查詢頻次較高且數(shù)據(jù)量大的表建立索引,索引選擇使用頻次較高,過濾效果好的列或者組合;
  • 2、使用短索引;節(jié)點包含的信息多,較少磁盤 IO 操作;比如: smallint , tinyint ;
  • 3、對于很長的動態(tài)字符串,考慮使用前綴索引;
  • 4、對于組合索引,考慮最左側(cè)匹配原則、覆蓋索引;
  • 5、盡量選擇區(qū)分度高的列作為索引;該列的值相同的越少越好;
  • 6、盡量擴展索引,在現(xiàn)有索引的基礎(chǔ)上,添加復(fù)合索引;最多 6 個索引;
  • 7、不要 select * ; 盡量只列出需要的列字段;方便使用覆蓋索引;
  • 8、索引列,列盡量設(shè)置為非空;
  • 9、可以開啟自適應(yīng) hash 索引或者調(diào)整 change buffer;

四、怎么解決慢的問題

我們通過使用 EXPLAIN 來查看 SQL 語句的具體執(zhí)行過程。 原理:模擬優(yōu)化器執(zhí)行 SQL 查詢語句,從而知道 MySQL 是如何處理 SQL 語句的。

首先我們需要找到SQL這個語句在哪里,通過 show processlist 列出較慢的連接通道來 以及使用慢查詢?nèi)罩緛碚业骄唧w的SQL語句。再分析SQL中我們要先查看在where、group by、order by中是否使用索引,如果沒有使用,那么就可以考慮是否添加索引,然后繼續(xù)優(yōu)化SQL語句中in和not in 變成聯(lián)合查詢,并且減少整體的聯(lián)合查詢。以及一個隱形的問題:age問題,應(yīng)該存儲出生年月,讓客戶端進行計算年紀。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • IDEA使用mybatis-generator及配上mysql8.0.3版本遇到的bug

    IDEA使用mybatis-generator及配上mysql8.0.3版本遇到的bug

    這篇文章主要介紹了IDEA使用mybatis-generator以及配上mysql8.0.3版本遇到的問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • MySQL復(fù)合查詢操作實戰(zhàn)案例

    MySQL復(fù)合查詢操作實戰(zhàn)案例

    這篇文章主要給大家介紹了關(guān)于MySQL復(fù)合查詢操作的相關(guān)資料,MySQL復(fù)合查詢是指在一個SQL語句中使用多個查詢條件,以過濾和檢索數(shù)據(jù),需要的朋友可以參考下
    2023-08-08
  • 關(guān)于Mysql中current_time/current_date()與now()區(qū)別

    關(guān)于Mysql中current_time/current_date()與now()區(qū)別

    這篇文章主要介紹了關(guān)于current_time/current_date()與now()區(qū)別,在Mysql中 current_time函數(shù)是顯示當前時間的,而其他兩個函數(shù)有何不同呢, 接下來我們就一起來看看吧
    2023-04-04
  • mysql如何才能保證數(shù)據(jù)的一致性

    mysql如何才能保證數(shù)據(jù)的一致性

    這篇文章主要介紹了mysql如何才能保證數(shù)據(jù)的一致性問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教<BR>
    2024-03-03
  • MySQL中日期比較時遇到的編碼問題解決辦法

    MySQL中日期比較時遇到的編碼問題解決辦法

    這篇文章主要介紹了MySQL中日期比較時遇到的字符集問題解決辦法,本文遇到的問題是date_format函數(shù)和timediff函數(shù)之間比較時,編碼問題導(dǎo)致出錯,本文使用convert()函數(shù)解決了這個問題,需要的朋友可以參考下
    2014-07-07
  • Ubuntu系統(tǒng)安裝與配置MySQL

    Ubuntu系統(tǒng)安裝與配置MySQL

    這篇文章介紹了Ubuntu系統(tǒng)安裝與配置MySQL的方法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • MySQL數(shù)據(jù)定義語言DDL的基礎(chǔ)語句

    MySQL數(shù)據(jù)定義語言DDL的基礎(chǔ)語句

    這篇文章主要介紹了MySQL數(shù)據(jù)定義語言DDL的基礎(chǔ)語句,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • MySQL進階查詢、聚合查詢和聯(lián)合查詢

    MySQL進階查詢、聚合查詢和聯(lián)合查詢

    這篇文章主要介紹了MySQL數(shù)據(jù)庫的進階查詢,聚合查詢及聯(lián)合查詢,文中有詳細的代碼示例,需要的朋友可以參考閱讀
    2023-04-04
  • Mysql數(shù)據(jù)庫雙機熱備難點分析

    Mysql數(shù)據(jù)庫雙機熱備難點分析

    本文主要給大家介紹了在Mysql數(shù)據(jù)庫雙機熱備其中的難點分析以及重要環(huán)節(jié)的經(jīng)驗心得,需要的朋友收藏分享下吧。
    2017-12-12
  • mysql實現(xiàn)查詢結(jié)果導(dǎo)出csv文件及導(dǎo)入csv文件到數(shù)據(jù)庫操作

    mysql實現(xiàn)查詢結(jié)果導(dǎo)出csv文件及導(dǎo)入csv文件到數(shù)據(jù)庫操作

    這篇文章主要介紹了mysql實現(xiàn)查詢結(jié)果導(dǎo)出csv文件及導(dǎo)入csv文件到數(shù)據(jù)庫操作,結(jié)合實例形式分析了mysql相關(guān)數(shù)據(jù)庫導(dǎo)出、導(dǎo)入語句使用方法及操作注意事項,需要的朋友可以參考下
    2018-07-07

最新評論