最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

圖文詳解Mysql索引的最左前綴原則

 更新時間:2022年03月24日 12:46:07   作者:碼農(nóng)研究僧  
最左前綴原則是發(fā)生在復合索引上的,只有復合索引才會有所謂的左和右之分,下面這篇文章主要給大家介紹了關于Mysql索引的最左前綴原則的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

前言

之所以有這個最左前綴索引

歸根結底是mysql的數(shù)據(jù)庫結構 B+樹

在實際問題中 比如

索引index (a,b,c)有三個字段,

使用查詢語句select * from table where c = '1' ,sql語句不會走index索引的

select * from table where b =‘1’ and c ='2' 這個語句也不會走index索引

1. 定義

最左前綴匹配原則:在MySQL建立聯(lián)合索引時會遵守最左前綴匹配原則,即最左優(yōu)先,在檢索數(shù)據(jù)時從聯(lián)合索引的最左邊開始匹配

為了更好辨別這種情況,通過建立表格以及索引的情況進行分析

2. 全索引順序

建立一張表,建立一個聯(lián)合索引,如果順序顛倒,其實還是可以識別的,但是一定要有它的全部部分

建立表

CREATE TABLE staffs(
	id INT PRIMARY KEY AUTO_INCREMENT,
	`name` VARCHAR(24) NOT NULL DEFAULT'' COMMENT'姓名',
	`age` INT NOT NULL DEFAULT 0 COMMENT'年齡',
	`pos` VARCHAR(20) NOT NULL DEFAULT'' COMMENT'職位',
	`add_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT'入職時間'
)CHARSET utf8 COMMENT'員工記錄表';

INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('z3',22,'manager',NOW());
INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('July',23,'dev',NOW());
INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('2000',23,'dev',NOW());

建立索引ALTER TABLE staffs ADD INDEX index_staffs_nameAgePos(name,age,pos);

索引的順序位name-age-pos

顯示其索引有沒有show index from staffs;

通過顛倒其左右順序,其執(zhí)行都是一樣的

主要的語句是這三句

  1. explain select *from staffs where name='z3'and age=22 and pos='manager';
  2. explain select *from staffs where pos='manager' and name='z3'and age=22;
  3. explain select *from staffs where age=22 and pos='manager' and name='z3';

以上三者的順序顛倒,都使用到了聯(lián)合索引

最主要是因為MySQL中有查詢優(yōu)化器explain,所以sql語句中字段的順序不需要和聯(lián)合索引定義的字段順序相同,查詢優(yōu)化器會判斷糾正這條SQL語句以什么樣的順序執(zhí)行效率高,最后才能生成真正的執(zhí)行計劃

不論以何種順序都可使用到聯(lián)合索引

3. 部分索引順序

3.1 正序

如果是按照順序(缺胳膊斷腿的),都是一樣的

  1. explain select *from staffs where name=‘z3’;
  2. explain select *from staffs where name='z3’and age=22;
  3. explain select *from staffs where name='z3’and age=22;

其type都是ref類型,但是其字段長度會有微小變化,也就是它定義的字長長度變化而已

3.2 亂序

如果部分索引的順序打亂

  1. 只查第一個索引explain select *from staffs where name='z3';
  2. 跳過中間的索引 explain select *from staffs where name='z3' and pos='manager';
  3. 只查最后的索引 explain select *from staffs where pos='manager';

可以發(fā)現(xiàn)正序的時候

如果缺胳膊少腿,也是按照正常的索引

即使跳過了中間的索引,也是可以使用到索引去查詢

但是如果只查最后的索引

type就是all類型,直接整個表的查詢了(這是因為沒有從name一開始匹配,直接匹配pos的話,會顯示無序,)

有些時候type就是index類型,這是因為還是可以通過索引進行查詢

index是對所有索引樹進行掃描,而all是對整個磁盤的數(shù)據(jù)進行全表掃描

4. 模糊索引

類似模糊索引就會使用到like的語句

所以下面的三條語句

如果復合最左前綴的話,會使用到range或者是index的類型進行索引

  1. explain select *from staffs where name like '3%'; 最左前綴索引,類型為index或者range
  2. explain select *from staffs where name like '%3%'; 類型為all,全表查詢
  3. explain select *from staffs where name like '%3%';,類型為all,全表查詢

5. 范圍索引

如果查詢多個字段的時候,出現(xiàn)了中間是范圍的話,建議刪除該索引,剔除中間索引即可

具體思路如下

建立一張單表

CREATE TABLE IF NOT EXISTS article(
	id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
	author_id INT(10) UNSIGNED NOT NULL,
	category_id INT(10) UNSIGNED NOT NULL,
	views INT(10) UNSIGNED NOT NULL,
	comments INT(10) UNSIGNED NOT NULL,
	title VARCHAR(255) NOT NULL,
	content TEXT NOT NULL
);

INSERT INTO article(author_id,category_id,views,comments,title,content)
VALUES
(1,1,1,1,'1','1'),
(2,2,2,2,'2','2'),
(1,1,3,3,'3','3');

經(jīng)過如下查詢:

explain SELECT id, author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT 1;

發(fā)現(xiàn)其上面的單表查詢,不是索引的話,他是進行了全表查詢,而且在extra還出現(xiàn)了Using filesort等問題

所以思路可以有建立其復合索引

具體建立復合索引有兩種方式:

  1. create index idx_article_ccv on article(category_id,comments,views);
  2. ALTER TABLE 'article' ADD INDEX idx_article_ccv ( 'category_id , 'comments', 'views' );

但這只是去除了它的范圍,如果要去除Using filesort問題的話,還要將其中間的條件范圍改為等于號才可滿足

發(fā)現(xiàn)其思路不行,所以刪除其索引 DROP INDEX idx_article_ccv ON article;

主要的原因是:

這是因為按照BTree索引的工作原理,先排序category_id,如果遇到相同的category_id則再排序comments,如果遇到相同的comments 則再排序views。

當comments字段在聯(lián)合索引里處于中間位置時,因comments > 1條件是一個范圍值(所謂range),MySQL無法利用索引再對后面的views部分進行檢索,即range類型查詢字段后面的索引無效。

所以建立復合索引是對的

但是其思路要避開中間那個范圍的索引進去

只加入另外兩個索引即可create index idx_article_cv on article(category_id, views);

總結

到此這篇關于通過Mysql索引的最左前綴原則的文章就介紹到這了,更多相關Mysql索引最左前綴原則內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MySQL報錯sql_mode=only_full_group_by的問題解決

    MySQL報錯sql_mode=only_full_group_by的問題解決

    本文主要介紹了MySQL報錯sql_mode=only_full_group_by的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-02-02
  • 一文帶你了解MySQL四大類日志

    一文帶你了解MySQL四大類日志

    在MySQL中日志文件可以分為4種:二進制日志文件、錯誤日志文件、通用查詢?nèi)罩疚募吐樵內(nèi)罩疚募?下面這篇文章主要給大家介紹了關于MySQL四大類日志的相關資料,需要的朋友可以參考下
    2023-04-04
  • MySQL 復制詳解及簡單實例

    MySQL 復制詳解及簡單實例

    這篇文章主要介紹了MySQL 復制詳解及簡單實例的相關資料,需要的朋友可以參考下
    2017-04-04
  • MySQL在不知道列名情況下的注入詳解

    MySQL在不知道列名情況下的注入詳解

    這篇文章主要給大家介紹了關于MySQL在不知道列名情況下的注入的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用mysql具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-03-03
  • mysql之數(shù)據(jù)舊表導新表的實現(xiàn)示例

    mysql之數(shù)據(jù)舊表導新表的實現(xiàn)示例

    在MySQL中,可以通過INSERT INTO...SELECT * FROM...語句輕松復制兩個結構相同或目標表包含源表所有列的表中的數(shù)據(jù),本文就來介紹一下mysql之數(shù)據(jù)舊表導新表的實現(xiàn)示例,感興趣的可以了解一下
    2024-10-10
  • 基于sql語句的一些常用語法積累總結

    基于sql語句的一些常用語法積累總結

    本篇文章是對一些常用的sql語句進行了總結與分析,需要的朋友參考下
    2013-06-06
  • MySQL通過DQL實現(xiàn)對數(shù)據(jù)庫數(shù)據(jù)的條件查詢

    MySQL通過DQL實現(xiàn)對數(shù)據(jù)庫數(shù)據(jù)的條件查詢

    這篇文章給大家介紹了MySQL如何通過DQL進行數(shù)據(jù)庫數(shù)據(jù)的條件查詢,文中通過代碼示例和圖文結合介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • 為什么說MySQL不建議使用delete刪除數(shù)據(jù)

    為什么說MySQL不建議使用delete刪除數(shù)據(jù)

    MySQL的DELETE語句是數(shù)據(jù)刪除的核心工具,支持條件刪除、多表關聯(lián)刪除及條數(shù)限制等高級功能,這篇文章主要介紹了為什么MySQL不建議使用delete刪除數(shù)據(jù)的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2026-03-03
  • 一文讀懂MySQL?表分區(qū)

    一文讀懂MySQL?表分區(qū)

    MySQL自帶了分區(qū)功能,我們可以創(chuàng)建一個帶有分區(qū)的表,而且不需要借助任何外部工具,本文主要了介紹了MySQL表分區(qū),具有一定的參考價值,感興趣的小伙伴們可以參考一下<BR>
    2022-03-03
  • Mysql中的find_in_set的使用方法介紹

    Mysql中的find_in_set的使用方法介紹

    Mysql中的find_in_set的使用方法介紹,需要的朋友可以參考一下
    2013-03-03

最新評論

施秉县| 大洼县| 福安市| 日土县| 六枝特区| 理塘县| 德安县| 莱州市| 水城县| 余姚市| 岱山县| 工布江达县| 光山县| 鄂尔多斯市| 威信县| 香河县| 尼勒克县| 南充市| 吴川市| 松潘县| 渝北区| 宁乡县| 准格尔旗| 镇坪县| 中宁县| 青阳县| 龙井市| 白城市| 富锦市| 察隅县| 建瓯市| 谢通门县| 濮阳县| 沙河市| 黎川县| 禄丰县| 龙胜| 陵水| 修水县| 阳春市| 清徐县|