濮阳杆衣贸易有限公司

主頁 > 知識(shí)庫 > 90%程序員面試會(huì)遇到的索引優(yōu)化問題

90%程序員面試會(huì)遇到的索引優(yōu)化問題

熱門標(biāo)簽:怎么去開發(fā)一個(gè)電銷機(jī)器人 小程序智能電話機(jī)器人 南昌呼叫中心外呼系統(tǒng)哪家好 簡(jiǎn)單的智能語音電銷機(jī)器人 泗洪正規(guī)電話機(jī)器人找哪家 怎么申請(qǐng)400熱線電話 湖南保險(xiǎn)智能外呼系統(tǒng)產(chǎn)品介紹 河北便宜電銷機(jī)器人軟件 ai電話電話機(jī)器人

前言

本文給大家分享了90%程序員面試都用得上的索引優(yōu)化,重點(diǎn)提一下,索引基本原理和創(chuàng)建索引的原則是重點(diǎn),面試基本必問!大家可以收藏好多理解理解。下面來一起看看詳細(xì)的介紹吧。

關(guān)于索引,分為以下幾點(diǎn)來講解(技術(shù)文):

  • 索引的概述(什么是索引,索引的優(yōu)缺點(diǎn))
  • 索引的基本使用(創(chuàng)建索引)
  • 索引的基本原理(面試重點(diǎn))
  • 索引的數(shù)據(jù)結(jié)構(gòu)(B樹,hash)
  • 創(chuàng)建索引的原則(重中之重,面試必問!敬請(qǐng)收藏!)
  • 百萬級(jí)別或以上的數(shù)據(jù)如何刪除

一、索引的概述

1)什么是索引?

索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。更通俗的說,索引就相當(dāng)于目錄。當(dāng)你在用新華字典時(shí),幫你把目錄撕掉了,你查詢某個(gè)字開頭的成語只能從第一頁翻到第一千頁。累!把目錄還給你,則能快速定位!

2)索引的優(yōu)缺點(diǎn):

可以大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要的原因。,且通過使用索引,可以在查詢的過程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能。但是,索引也是有缺點(diǎn)的:索引需要額外的維護(hù)成本;因?yàn)樗饕募菃为?dú)存在的文件,對(duì)數(shù)據(jù)的增加,修改,刪除,都會(huì)產(chǎn)生額外的對(duì)索引文件的操作,這些操作需要消耗額外的IO,會(huì)降低增/改/刪的執(zhí)行效率。

二、索引的基本使用(真技術(shù)文)

1)創(chuàng)建索引:(三種方式)

第一種方式:


第二種方式:使用ALTER TABLE命令去增加索引:

ALTER TABLE用來創(chuàng)建普通索引、UNIQUE索引或PRIMARY KEY索引。


其中table_name是要增加索引的表名,column_list指出對(duì)哪些列進(jìn)行索引,多列時(shí)各列之間用逗號(hào)分隔。

索引名index_name可自己命名,缺省時(shí),MySQL將根據(jù)第一個(gè)索引列賦一個(gè)名稱。另外,ALTER TABLE允許在單個(gè)語句中更改多個(gè)表,因此可以在同時(shí)創(chuàng)建多個(gè)索引。

第三種方式:使用CREATE INDEX命令創(chuàng)建

CREATE INDEX可對(duì)表增加普通索引或UNIQUE索引。(但是,不能創(chuàng)建PRIMARY KEY索引)


三、索引的基本原理(不想像別的文章那樣一大堆篇幅廢話)

索引用來快速地尋找那些具有特定值的記錄。如果沒有索引,一般來說執(zhí)行查詢時(shí)遍歷整張表。

索引的原理很簡(jiǎn)單,就是把無序的數(shù)據(jù)變成有序的查詢

      1、把創(chuàng)建了索引的列的內(nèi)容進(jìn)行排序

      2、對(duì)排序結(jié)果生成倒排表

      3、在倒排表內(nèi)容上拼上數(shù)據(jù)地址鏈

      4、在查詢的時(shí)候,先拿到倒排表內(nèi)容,再取出數(shù)據(jù)地址鏈,從而拿到具體數(shù)據(jù)

四、索引的數(shù)據(jù)結(jié)構(gòu)(b樹,hash)

1)B樹索引

mysql通過存儲(chǔ)引擎取數(shù)據(jù),基本上90%的人用的就是InnoDB了,按照實(shí)現(xiàn)方式分,InnoDB的索引類型目前只有兩種:BTREE(B樹)索引和HASH索引。B樹索引是Mysql數(shù)據(jù)庫中使用最頻繁的索引類型,基本所有存儲(chǔ)引擎都支持BTree索引。通常我們說的索引不出意外指的就是(B樹)索引(實(shí)際是用B+樹實(shí)現(xiàn)的,因?yàn)樵诓榭幢硭饕龝r(shí),mysql一律打印BTREE,所以簡(jiǎn)稱為B樹索引)


查詢方式:

主鍵索引區(qū):PI(關(guān)聯(lián)保存的時(shí)數(shù)據(jù)的地址)按主鍵查詢,

普通索引區(qū):si(關(guān)聯(lián)的id的地址,然后再到達(dá)上面的地址)。所以按主鍵查詢,速度最快

B+tree性質(zhì):

1.)n棵子tree的節(jié)點(diǎn)包含n個(gè)關(guān)鍵字,不用來保存數(shù)據(jù)而是保存數(shù)據(jù)的索引。

2.)所有的葉子結(jié)點(diǎn)中包含了全部關(guān)鍵字的信息,及指向含這些關(guān)鍵字記錄的指針,且葉子結(jié)點(diǎn)本身依關(guān)鍵字的大小自小而大順序鏈接。

3.)所有的非終端結(jié)點(diǎn)可以看成是索引部分,結(jié)點(diǎn)中僅含其子樹中的最大(或最?。╆P(guān)鍵字。

4.)B+ 樹中,數(shù)據(jù)對(duì)象的插入和刪除僅在葉節(jié)點(diǎn)上進(jìn)行。

5.)B+樹有2個(gè)頭指針,一個(gè)是樹的根節(jié)點(diǎn),一個(gè)是最小關(guān)鍵碼的葉節(jié)點(diǎn)。

2)哈希索引(好技術(shù)文)

簡(jiǎn)要說下,類似于數(shù)據(jù)結(jié)構(gòu)中簡(jiǎn)單實(shí)現(xiàn)的HASH表(散列表)一樣,當(dāng)我們?cè)趍ysql中用哈希索引時(shí),主要就是通過Hash算法(常見的Hash算法有直接定址法、平方取中法、折疊法、除數(shù)取余法、隨機(jī)數(shù)法),將數(shù)據(jù)庫字段數(shù)據(jù)轉(zhuǎn)換成定長(zhǎng)的Hash值,與這條數(shù)據(jù)的行指針一并存入Hash表的對(duì)應(yīng)位置;如果發(fā)生Hash碰撞(兩個(gè)不同關(guān)鍵字的Hash值相同),則在對(duì)應(yīng)Hash鍵下以鏈表形式存儲(chǔ)。當(dāng)然這只是簡(jiǎn)略模擬圖。


ps:關(guān)于數(shù)據(jù)結(jié)構(gòu),有興趣深入的朋友可以關(guān)注我后查看【數(shù)據(jù)結(jié)構(gòu)】專題,這里不做詳細(xì)講解。

五、創(chuàng)建索引的原則(重中之重)

索引雖好,但也不是無限制的使用,最好符合一下幾個(gè)原則

1) 最左前綴匹配原則,組合索引非常重要的原則,mysql會(huì)一直向右匹配直到遇到范圍查詢(>、、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調(diào)整。

2)較頻繁作為查詢條件的字段才去創(chuàng)建索引

3)更新頻繁字段不適合創(chuàng)建索引

4)若是不能有效區(qū)分?jǐn)?shù)據(jù)的列不適合做索引列(如性別,男女未知,最多也就三種,區(qū)分度實(shí)在太低)

5)盡量的擴(kuò)展索引,不要新建索引。比如表中已經(jīng)有a的索引,現(xiàn)在要加(a,b)的索引,那么只需要修改原來的索引即可。

6)定義有外鍵的數(shù)據(jù)列一定要建立索引。

7)對(duì)于那些查詢中很少涉及的列,重復(fù)值比較多的列不要建立索引。

8)對(duì)于定義為text、image和bit的數(shù)據(jù)類型的列不要建立索引。

百萬級(jí)別或以上的數(shù)據(jù)如何刪除(真好技術(shù)文)

關(guān)于索引:由于索引需要額外的維護(hù)成本,因?yàn)樗饕募菃为?dú)存在的文件,所以當(dāng)我們對(duì)數(shù)據(jù)的增加,修改,刪除,都會(huì)產(chǎn)生額外的對(duì)索引文件的操作,這些操作需要消耗額外的IO,會(huì)降低增/改/刪的執(zhí)行效率。所以,在我們刪除數(shù)據(jù)庫百萬級(jí)別數(shù)據(jù)的時(shí)候,查詢MySQL官方手冊(cè)得知?jiǎng)h除數(shù)據(jù)的速度和創(chuàng)建的索引數(shù)量是成正比的。

  • 所以我們想要?jiǎng)h除百萬數(shù)據(jù)的時(shí)候可以先刪除索引(此時(shí)大概耗時(shí)三分多鐘)
  • 然后刪除其中無用數(shù)據(jù)(此過程需要不到兩分鐘)
  • 刪除完成后重新創(chuàng)建索引(此時(shí)數(shù)據(jù)較少了)創(chuàng)建索引也非???,約十分鐘左右。
  • 與之前的直接刪除絕對(duì)是要快速很多,更別說萬一刪除中斷,一切刪除會(huì)回滾。那更是坑了。

常用的數(shù)據(jù)庫索引優(yōu)化語句

使用如下的表tb_test作為示例進(jìn)行說明:

create table tb_test
(
id int not null,
age int not null, 
name varchar(30) not null,
addr varchar(50) not null
);
create unique index idx1_tb_test on tb_test(id);
create index idx2_tb_test on tb_test(name);
create index idx3_tb_test on tb_test(addr);

索引優(yōu)化建議

1.對(duì)索引列進(jìn)行計(jì)算

例如,我們想要將表tb_test中id大于100的數(shù)據(jù)記錄中的age和name查找出來。

正確的SQL語句是:

select age,name from tb_test where id > 1*100;

不建議采用的SQL語句是:

select age,name from tb_test where id/100 > 1;

2.對(duì)索引列進(jìn)行拼接

例如,我們想要將表tb_test中name為“zhou”、addr為“CQ”的記錄中的id和age查找出來。

正確的SQL語句是:

select id,age from tb_test where name='zhou' and addr='CQ';

不建議采用的SQL語句是:

select id,age from tb_test where concat(name,' ‘,addr) = ‘zhou CQ';

3.在索引列上is null或is not null的使用

例如,我們想要將表tb_test中id大于等于“0”的記錄中的age查找出來。

正確的SQL語句是:

select age from tb_test where id >= 0;

不建議采用的SQL語句是:

select age from tb_test where id is not null;

4.在索引列上or的使用

例如,我們想要將表tb_test中id等于101或102的記錄中的age和name查找出來。

正確的SQL語句(使用union)是:

select age,name from tb_test where id = 101 union select age,name from tb_test where id = 102;

不建議采用的SQL語句(使用or)是:

select age,name from tb_test where id = 101 or id = 102;

5.盡可能避免索引列在like的首字符使用通配符

例如,我們想要將表tb_test中name匹配“zho”的記錄中的id和age查找出來。

正確的SQL語句是:

select id,age from tb_test where name like ‘zho%';

不建議采用的SQL語句是:

select id,age from tb_test where name like ‘%ho%';

6.復(fù)合索引的使用

如果我們建立的索引是復(fù)合索引,那么必須使用到該索引中的第一個(gè)字段作為條件時(shí)才能保證系統(tǒng)使用該索引。

例如,我們?cè)诒韙b_test上新建了如下索引:

create index idx4_tb_test on tb_test(id,name,addr);

以上索引idx4_tb_test相當(dāng)于建立了index(id)、index(id,name)、index(id,name,addr) 這3個(gè)索引。在SQL語句的where條件中單獨(dú)使用name或addr時(shí)不會(huì)使用到該索引,必須使用id時(shí)才會(huì)使用到該索引。

在我們編寫的SQL語句中,不正確地使用索引列可能會(huì)導(dǎo)致索引不被使用,而進(jìn)行全表掃描,極大地降低了數(shù)據(jù)庫的性能。因此,學(xué)習(xí)正確的索引的使用方法實(shí)在是很有必要的。

今天,索引的講解就到這里,重點(diǎn)提一下,索引基本原理和創(chuàng)建索引的原則是重點(diǎn),面試基本必問!大家可以收藏好多理解理解。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

您可能感興趣的文章:
  • MySQL 索引分析和優(yōu)化
  • mysql性能優(yōu)化之索引優(yōu)化
  • SQL優(yōu)化基礎(chǔ) 使用索引(一個(gè)小例子)
  • MySQL索引背后的之使用策略及優(yōu)化(高性能索引策略)
  • Mysql limit 優(yōu)化,百萬至千萬級(jí)快速分頁 復(fù)合索引的引用并應(yīng)用于輕量級(jí)框架
  • MySQL 聯(lián)合索引與Where子句的優(yōu)化 提高數(shù)據(jù)庫運(yùn)行效率
  • MySQL中索引優(yōu)化distinct語句及distinct的多字段操作
  • Mysql使用索引實(shí)現(xiàn)查詢優(yōu)化
  • MySQL Order By索引優(yōu)化方法
  • 搜索引擎優(yōu)化《SEO教程2007版》下載

標(biāo)簽:荊門 柳州 瀘州 景德鎮(zhèn) 那曲 威海 江蘇 淮安

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《90%程序員面試會(huì)遇到的索引優(yōu)化問題》,本文關(guān)鍵詞  90%,程序員,面試,會(huì),遇到,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《90%程序員面試會(huì)遇到的索引優(yōu)化問題》相關(guān)的同類信息!
  • 本頁收集關(guān)于90%程序員面試會(huì)遇到的索引優(yōu)化問題的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    年辖:市辖区| 凤城市| 石家庄市| 额尔古纳市| 永新县| 东乌珠穆沁旗| 烟台市| 兴山县| 峡江县| 湘乡市| 婺源县| 忻州市| 蓬安县| 舒城县| 炉霍县| 罗江县| 秦安县| 娄底市| 延边| 蒙自县| 白城市| 彭山县| 平安县| 玉田县| 图片| 甘孜| 蒙山县| 合阳县| 四会市| 邳州市| 南投市| 博白县| 赤峰市| 湄潭县| 铁岭县| 托里县| 上栗县| 吐鲁番市| 凤山市| 太仆寺旗| 许昌市|