国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫 - 數(shù)據(jù)庫技術(shù) - 16 個該搞定的數(shù)據(jù)庫索引問題!

16 個該搞定的數(shù)據(jù)庫索引問題!

2021-12-27 23:29愛笑的架構(gòu)師雷小帥 數(shù)據(jù)庫技術(shù)

什么是索引呢?索引本質(zhì)是一種數(shù)據(jù)結(jié)構(gòu)(最常見的是 B+樹),是在表的列上創(chuàng)建的。

16 個該搞定的數(shù)據(jù)庫索引問題!

大家好,我是悟空呀,這次我們來細說下 MySQL 中的索引。

我們先從一個面試場景開始:

面試官:了解過數(shù)據(jù)庫索引嗎?

候選人:聽過一些,底層數(shù)據(jù)結(jié)構(gòu)好像是二叉樹,不對,好像是 B 樹,哦,我想起來了,好像是 B+樹……(像極了當(dāng)年面試的我)

面試官:聽過哈希索引嗎?

候選人:我知道哈希表,哈希索引沒聽過

面試官:今天面試先到這里了,回去等消息吧……

溫馨提示:本文是數(shù)據(jù)庫索引的簡單入門篇,后面會通過圖解的方式逐步帶大家深入索引的原理,敬請期待!

先引入一個簡單的示例,通過示例操作解釋一下為什么需要數(shù)據(jù)庫索引。

假設(shè)我們有一個名為 t_employee 的數(shù)據(jù)庫表,這個數(shù)據(jù)庫表有三列:name,age,address,數(shù)據(jù)量有上萬行。

如果我們想要查找所有名為「leixiaoshuai」員工的詳細信息,只需要寫一個簡單的 SQL 語句就可以搞定,相信大家都會寫。

  1. SELECT * FROM t_employee
  2. WHERE name = 'leixiaoshuai'

如果沒有索引,會發(fā)生什么?

一旦我們運行了這條 SQL 查詢語句,在數(shù)據(jù)庫內(nèi)部是如何工作的呢?數(shù)據(jù)庫會搜索 t_employee 表中的每一行,從而確定員工的名字(name)是否為 ‘leixiaoshuai’。由于我們想要得到每一個名字為 leixiaoshuai 的雇員信息,在查詢到第一個符合條件的行記錄后,不能停止查詢,因為可能還有其他符合條件的行。所以,必須一行一行的查找直到最后一行,這就意味數(shù)據(jù)庫不得不檢查上萬行數(shù)據(jù)才能找到所有名字為 leixiaoshuai 的員工。這就是所謂的 全表掃描

數(shù)據(jù)庫索引如何幫助提高性能?

你可能會想:「這么簡單的查詢語句居然還需要全表掃描,數(shù)據(jù)庫也太笨了吧?!」

這就類似于用人眼從頭到尾逐字逐句讀一本書,效率太低了!

那應(yīng)該怎么辦?聰明的你肯定想到解決方案了:「加個索引啊」。

這就是索引派上用場的時候了,使用索引的目的就是**通過減少表中需要檢查的記錄/行的數(shù)量來加速搜索查詢。**說的再簡單點:「索引就是用來加速查詢的」。

什么是索引?

那么問題來了,什么是索引呢?索引本質(zhì)是一種數(shù)據(jù)結(jié)構(gòu)(最常見的是 B+樹),是在表的列上創(chuàng)建的。

索引的數(shù)據(jù)結(jié)構(gòu)是什么樣的?

常見MySQL索引一般分為: Hash索引 和**B+**樹索引,InnoDB引擎中默認的是B+樹。

B+樹是最常用于索引的數(shù)據(jù)結(jié)構(gòu),時間復(fù)雜度低:查找、刪除、插入操作都可以可以在 logn 時間內(nèi)完成。另外一個重要原因存儲在 B+樹 中的數(shù)據(jù)是 有序的

在B+樹常規(guī)檢索場景下,從根節(jié)點到葉子節(jié)點的搜索效率基本相當(dāng),不會出現(xiàn)大幅波動,而且基于索引的順序掃描時,也可以利用雙向指針快速左右移動,效率非常高。

哈希索引就是采用一定的哈希算法,把鍵值換算成新的哈希值,檢索時不需要類似B+樹那樣從根節(jié)點到葉子節(jié)點逐級查找,只需一次哈希算法即可立刻定位到相應(yīng)的位置,速度非常快。

哈希表索引是如何工作的?

如果你在創(chuàng)建索引時指定數(shù)據(jù)結(jié)構(gòu)為「哈希表」,那這些索引也可稱為「哈希索引」。

哈希索引的優(yōu)點非常明顯,在一定場景下,檢索指定值時哈希表的效率極高。比如上面我們討論的一個查詢語句:SELECT * FROM t_employee WHERE name = ‘leixiaoshuai’,如果在 name 列上加一個哈希索引,檢索速度有可能會成倍提升。

哈系索引的工作方式是將列的值作為索引的鍵值(key),鍵值相對應(yīng)實際的值(value)是指向該表中相應(yīng)行的指針。因為哈希表基本上可以看作是關(guān)聯(lián)數(shù)組,一個典型的數(shù)據(jù)項就像 「leixiaoshuai => 0x996996」,而 0x996996 是對內(nèi)存中表中包含 leixiaoshuai 這一行的引用。在哈系索引的中查詢一個像 leixiaoshuai 這樣的值,并得到對應(yīng)行的在內(nèi)存中的引用,明顯要比掃描全表獲得值為 leixiaoshuai 的行的方式快很多。

哈希索引的缺點

上面說了哈希索引的優(yōu)點,那哈希索引的缺點也是繞不過去的。

哈希表是無順的數(shù)據(jù)結(jié)構(gòu),對于很多類型的查詢語句哈希索引都無能為力。舉例來說,假如你想要找出所有小于40歲的員工。你怎么使用使用哈希索引進行查詢?這不可行,因為哈希表只適合查詢鍵值對,也就是說查詢相等的查詢(例:like “WHERE name = ‘leixiaoshuai’)。哈希表的鍵值映射也暗示其鍵的存儲是無序的。這就是為什么哈希索引通常不是數(shù)據(jù)庫索引的默認數(shù)據(jù)結(jié)構(gòu), 因為在作為索引的數(shù)據(jù)結(jié)構(gòu)時,其不像B+Tree那么靈活

總結(jié)一下缺點:

  • (1)不支持范圍查詢

  • (2)不支持索引完成排序

  • (3)不支持聯(lián)合索引的最左前綴匹配規(guī)則

還有什么其他類型的索引?

常見的還有:R 樹和位圖索引。

R 樹通常用來為空間問題提供幫助。例如,一個查詢要求“查詢出所有距離我兩公里之內(nèi)的麥當(dāng)勞”,如果數(shù)據(jù)庫表使用R樹索引,這類查詢的效率將會提高。

位圖索引(bitmap index), 這類索引適合放在包含布爾值(true 和 false)的列上。

索引如何提高性能?

因為索引基本上是用來存儲列值的數(shù)據(jù)結(jié)構(gòu),這使查找這些列值更加快速。如果索引使用B+樹數(shù)據(jù)結(jié)構(gòu),那么其中的數(shù)據(jù)是有序的,有序的列值可以極大的提升性能。

假如我們在 name 這一列上創(chuàng)建一個 B+樹 索引,這意味著當(dāng)我們用之前的SQL查找name=‘leixiaoshuai‘時不需要再掃描全表,而是用索引查找去查找名字為‘leixiaoshuai’的員工,因為索引已經(jīng)按照按字母順序排序。索引 已經(jīng)排序 意味著查詢一個名字會快很多,因為名字少字母為‘L’的員工都是排列在一起的。另外重要的一點是,索引同時存儲了表中相應(yīng)行的指針以獲取其他列的數(shù)據(jù)。

數(shù)據(jù)庫索引中到底存的是什么?

你現(xiàn)在已經(jīng)知道數(shù)據(jù)庫索引是創(chuàng)建在表的某列上的,并且存儲了這一列的所有值。但是需要理解的重點是 數(shù)據(jù)庫索引并不存儲這個表中其他列(字段)的值 。舉例來說,如果我們在 name 列創(chuàng)建索引,那么 age 列和 address 列上的值并不會存儲在這個索引當(dāng)中。如果我們確實把其他所有字段也存儲在個這個索引中,那這樣會占用太大的空間而且會十分低效。

索引還存儲指向表行的指針

如果我們在索引里找到某一條記錄作為索引的列的值,如何才能找到這一條記錄的其它值呢?

這很簡單,數(shù)據(jù)庫索引同時存儲了指向表中的相應(yīng)行的指針。指針是指一塊內(nèi)存區(qū)域, 該內(nèi)存區(qū)域記錄的是對硬盤上記錄的相應(yīng)行的數(shù)據(jù)的引用。因此,索引中除了存儲列的值,還存儲著一個指向在行數(shù)據(jù)的索引。也就是說,索引中的name這列的某個值(或者節(jié)點)可以描述為 (“l(fā)eixiaoshuai”, 0x996996), 0x996996 就是包含 “l(fā)eixiaoshuai”那行數(shù)據(jù)在硬盤上的地址。如果沒有這個引用,你就只能訪問到一個單獨的值(“l(fā)eixiaoshuai”),而這樣沒有意義,因為你不能獲取這一行記錄的employee的其他值-例如地址(address)和年齡(age)。

數(shù)據(jù)庫如何知道何時使用索引?

當(dāng)你運行一條查詢 SQL 語句時,數(shù)據(jù)庫會檢查在查詢的列上是否有索引。假設(shè) name 列上確實創(chuàng)建了索引,數(shù)據(jù)庫會接著檢查使用這個索引做查詢是否合理 ,因為有些場景下,使用索引比起全表掃描會更加低效。

可以強制數(shù)據(jù)庫在查詢中使用索引嗎?

通常來說, 你不會告訴數(shù)據(jù)庫什么時候使用索引,數(shù)據(jù)庫自己決定。

如何在SQL中創(chuàng)建索引?

下面是在前面示例中的Employee_Name列上創(chuàng)建索引時實際SQL的外觀:

  1. CREATE INDEX name_index
  2. ON t_employee (name)

如何在SQL中創(chuàng)建聯(lián)合(多列)索引?

我們可以在age 和 address 兩列上創(chuàng)建聯(lián)合索引,SQL如下:

  1. CREATE INDEX age_address_index
  2. ON t_employee (age, address)

可以把數(shù)據(jù)庫索引類比成什么?

一個非常好的類比是把數(shù)據(jù)庫索引看作是書的索引。

你從頭到尾逐字逐行讀完就是「全表掃描」;

你翻看目錄挑選感興趣的部分閱讀就是走了索引。

使用數(shù)據(jù)庫索引有什么代價?

既然索引優(yōu)點這么多,那給所有列加上索引不就完事了,no no no,加索引是有代價的。

(1)索引會占用空間。你的表越大,索引占用的空間越大。

(2)在更新操作有性能損失。當(dāng)你在表中添加、刪除或者更新行數(shù)據(jù)的時候, 在索引中也會有相同的操作。

基本原則是:如果表中某列在查詢過程中使用的非常頻繁,那就在該列上創(chuàng)建索引。

參考:

  1. How do database indexes work? And, how do indexes help? Provide a tutorial on database indexes.

  2. 數(shù)據(jù)庫索引漫談

原文鏈接:https://mp.weixin.qq.com/s?__biz=MzAwMjI0ODk0NA==&mid=2451961692&idx=1&sn=5ad38a4a2514c9d50519235531007a23&utm_source=tuicool&utm_medium=referral

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲国产高清在线 | 欧美精品欧美精品系列 | 老司机午夜影院 | 毛片久久久久久 | 日韩高清一区 | 黄色小视频在线免费观看 | 欧美日韩综合精品 | 亚洲电影一区二区 | 色图自拍偷拍 | av在线日韩 | 91在线视频观看 | 国产精品一区二区免费 | 国产视频自拍一区 | 久久久久久久久99精品 | 亚洲天堂av影院 | 丝袜美腿一区二区三区 | 一级黄色片a级 | 欧美一区二区三区 | 黄色精品网站 | 日韩在线观看中文字幕 | 狠狠综合| 国产精品一区二区三区免费 | 国产区区| 成年人xxxx| 精品久久一区二区三区 | 在线成年人电影 | 国产高清在线看 | 精品一区二区久久久久久久网站 | 亚洲一区二区三区精品动漫 | 成人片网址 | 在线看黄色毛片 | 黄色在线免费观看视频网站 | 成人精品视频在线观看 | 午夜精品福利电影 | 久久99这里只有精品 | 精品久久久久久久久久久久久久 | 成人av在线播放 | 午夜小电影 | 日韩在线精品视频 | 久草福利资源 | 午夜在线影院 |