日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

mysql IS NULL使用索引案例講解

瀏覽:26日期:2023-10-26 13:10:28
簡(jiǎn)介

mysql的sql查詢語(yǔ)句中使用is null、is not null、!=對(duì)索引并沒(méi)有任何影響,并不會(huì)因?yàn)閣here條件中使用了is null、is not null、!=這些判斷條件導(dǎo)致索引失效而全表掃描。

mysql官方文檔也已經(jīng)明確說(shuō)明is null并不會(huì)影響索引的使用。

MySQL can perform the same optimization on col_name IS NULL that it can use for col_name = constant_value. For example, MySQL can use indexes and ranges to search for NULL with IS NULL.

事實(shí)上,導(dǎo)致索引失效而全表掃描的通常是因?yàn)橐淮尾樵冎谢乇頂?shù)量太多。mysql計(jì)算認(rèn)為使用索引的時(shí)間成本高于全表掃描,于是mysql寧可全表掃描也不愿意使用索引。

案例

CREATE TABLE `user_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(11) DEFAULT NULL, `age` int(4) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index_name` (`name`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `user_info` (`id`, `name`, `age`) VALUES (’1’, ’tom’, ’18’);INSERT INTO `user_info` (`id`, `name`, `age`) VALUES (’2’, null, ’19’);INSERT INTO `user_info` (`id`, `name`, `age`) VALUES (’3’, ’cat’, ’20’);

執(zhí)行sql查詢時(shí)使用is null、is not null,發(fā)現(xiàn)依然使用的索引查詢,并沒(méi)有出現(xiàn)索引失效的問(wèn)題。

mysql IS NULL使用索引案例講解

mysql IS NULL使用索引案例講解

分析

分析上述現(xiàn)象,則需要詳細(xì)了解mysql索引的工作原理以及索引數(shù)據(jù)結(jié)構(gòu)。下面,分別通過(guò)工具解析和直接查看二進(jìn)制文件兩種方式分別分析mysql索引數(shù)據(jù)結(jié)構(gòu)。

工具解析

innodb_ruby是一個(gè)非常強(qiáng)大的mysql分析工具,可以用來(lái)輕松解析mysql的.ibd文件進(jìn)而深入理解mysql的數(shù)據(jù)結(jié)構(gòu)。

首先安裝innodb_ruby工具:

yum install -y rubygems ruby-devegem install innodb_ruby

innodb_ruby的功能很多,此處我們只需要用來(lái)解析mysql的索引結(jié)構(gòu),因此只需要如下的命令即可。更多的功能和命令詳見(jiàn)wiki。

innodb_space -s ibdata1 -T sakila/film -I PRIMARY index-recurse

解析主鍵索引:

$ innodb_space -s /usr/soft/mysql-5.6.31/data -T test/user_info -I PRIMARY index-recurseROOT NODE #3: 3 records, 89 bytes RECORD: (id=1) → (name='tom', age=18) RECORD: (id=2) → (name=:NULL, age=19) RECORD: (id=3) → (name='cat', age=20)

解析普通索引index_name:

$ innodb_space -s /usr/soft/mysql-5.6.31/data -T test/user_info -I index_name index-recurseROOT NODE #4: 3 records, 38 bytes RECORD: (name=:NULL) → (id=2) RECORD: (name='cat') → (id=3) RECORD: (name='tom') → (id=1)

通過(guò)解析工具數(shù)據(jù)mysql的索引結(jié)構(gòu)可以發(fā)現(xiàn),null值也被儲(chǔ)存到了索引樹中,并且null值被處理成最小的值放在index_name索引樹的最左側(cè)。

二進(jìn)制文件

找到user_info表對(duì)應(yīng)的物理文件user_info.ibd,通過(guò)軟件例如UltraEdit打開,直接定位到第5個(gè)數(shù)據(jù)頁(yè)(mysql默認(rèn)一個(gè)數(shù)據(jù)頁(yè)占用16KB)。

mysql IS NULL使用索引案例講解

如圖,這些二進(jìn)制數(shù)據(jù)就是index_name索引對(duì)應(yīng)的索引頁(yè)數(shù)據(jù),只挑選其中的索引記錄,展開如下:

最小記錄0x00010063

01 B2 01 00 02 00 29 記錄頭信息69 6E 66 69 6D 75 6D 最小記錄(固定值infimum)

最大記錄0x00010070

00 04 00 0B 00 00 記錄頭信息73 75 70 72 65 6D 75 6D 最大記錄(固定值supremum)

ID為1的索引0x0001007f

03 00 00 00 10 FF F1 記錄頭信息74 6F 6D 字段name的值:tom80 00 00 01 RowID:主鍵id的值為1

ID為2的索引0x0001008c

01 00 00 18 00 0B 記錄頭信息字段name的值:null80 00 00 02RowID:主鍵id的值為2

ID為3的索引0x00010097

03 00 00 00 20 FF E8 記錄頭信息63 61 74 字段name的值:cat80 00 00 03 RowID:主鍵id的值為3

最小記錄的記錄頭信息最后2字節(jié)00 29 -> 0x00010063偏移0x0029 -> 0x0001008C,即ID為2的索引位置;

ID為2的記錄頭信息最后2字節(jié)00 0B -> 0x0001008C偏移0x000B -> 0x00010097,即ID為3的索引位置;

ID為3的記錄頭信息最后2字節(jié)FF E8 -> 0x00010097偏移0xFFE8 -> 0x0001007F,即ID為1的索引位置;

ID為1的記錄頭信息最后2字節(jié)FF F1 -> 0x0001007F偏移0xFFF1 -> 0x00010070,最大記錄的記錄位置;

由此可見(jiàn)索引記錄是通過(guò)單向鏈表并以索引值排序串聯(lián)在一起,而null值被處理成最小的值放在了索引鏈表的最開始位置,也就是索引樹的最左側(cè)。與innodb_ruby工具解析出來(lái)的結(jié)果一致。

誤解原因

為何大眾誤解認(rèn)為is null、is not null、!=這些判斷條件會(huì)導(dǎo)致索引失效而全表掃描呢?

導(dǎo)致索引失效而全表掃描的通常是因?yàn)橐淮尾樵冎谢乇頂?shù)量太多。mysql計(jì)算認(rèn)為使用索引的時(shí)間成本高于全表掃描,于是mysql寧可全表掃描也不愿意使用索引。使用索引的時(shí)間成本高于全表掃描的臨界值可以簡(jiǎn)單得記憶為20%左右。

詳細(xì)的分析過(guò)程可以見(jiàn)筆者的另一篇博客:mysql回表致索引失效。

也就是如果一條查詢語(yǔ)句導(dǎo)致的回表范圍超過(guò)全部記錄的20%,則會(huì)出現(xiàn)索引失效的問(wèn)題。而is null、is not null、!=這些判斷條件經(jīng)常會(huì)出現(xiàn)在這些回表范圍很大的場(chǎng)景,然后被人誤解為是這些判斷條件導(dǎo)致的索引失效。

復(fù)現(xiàn)索引失效

復(fù)現(xiàn)索引失效,只需要回表范圍超過(guò)全部記錄的20%,如下插入1000條非null記錄。

delimiter //CREATE PROCEDURE init_user_info() BEGIN DECLARE indexNo INT;SET indexNo = 0;WHILE indexNo < 1000 DOSTART TRANSACTION; insert into user_info(name,age) values (concat(floor(rand()*1000000000)),floor(rand()*100));SET indexNo = indexNo + 1;COMMIT; END WHILE;END //delimiter ;call init_user_info();

此時(shí)user_info表中一共有1003條記錄,其中只有1條記錄的name值為null。那么is null判斷語(yǔ)句導(dǎo)致的回表記錄只有1/1003不會(huì)超過(guò)臨界值,而is not null判斷語(yǔ)句導(dǎo)致的回表記錄有1002/1003遠(yuǎn)遠(yuǎn)超過(guò)臨界值,將出現(xiàn)索引失效的現(xiàn)象。

由下兩圖也可以見(jiàn),is null依然正常使用索引,而is not null如預(yù)期由于回表率太高而寧可全表掃描也不使用索引。

mysql IS NULL使用索引案例講解

mysql IS NULL使用索引案例講解

使用mysql的optimizer tracing(mysql5.6版本開始支持)功能來(lái)分析sql的執(zhí)行計(jì)劃:

SET optimizer_trace='enabled=on';explain select * from user_info where name is not null;SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;

optimizer tracing輸出的執(zhí)行計(jì)劃可見(jiàn),該查詢下,使用全表掃描所需要的時(shí)間成本為206.9;而使用索引所需要的時(shí)間成本為1203.4,遠(yuǎn)遠(yuǎn)高于全表掃描。因此mysql最終選擇全表掃描而出現(xiàn)索引失效的現(xiàn)象。

{ 'rows_estimation': [{ 'table': '`user_info`', 'range_analysis': {'table_scan': { 'rows': 1004, // 全表掃描需要掃描1004條記錄 'cost': 206.9 // 全表掃描需要的成本為206.9},'potential_range_indices': [ {'index': 'PRIMARY','usable': false,'cause': 'not_applicable' }, {'index': 'index_name','usable': true,'key_parts': [ 'name', 'id'] }],'setup_range_conditions': [],'group_index_range': { 'chosen': false, 'cause': 'not_group_by_or_distinct'},'analyzing_range_alternatives': { 'range_scan_alternatives': [{ 'index': 'index_name', 'ranges': ['NULL < name' ], 'index_dives_for_eq_ranges': true, 'rowid_ordered': false, 'using_mrr': false, 'index_only': false, 'rows': 1002, // 索引需要掃描1002條記錄 'cost': 1203.4, // 索引需要的成本為1203.4 'chosen': false, 'cause': 'cost'} ], 'analyzing_roworder_intersect': {'usable': false,'cause': 'too_few_roworder_scans' }} }} ]}

到此這篇關(guān)于mysql IS NULL使用索引案例講解的文章就介紹到這了,更多相關(guān)mysql IS NULL使用內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: MySQL 數(shù)據(jù)庫(kù)
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品久久久网| 四季av一区二区凹凸精品| 欧美精品资源| 成人三级高清视频在线看| 久久精品免视看国产成人| 国产日韩一区二区三免费高清| 欧美亚洲三区| 国产精品久久乐| 国产精品2023| 欧美日韩18| 国产精品1区| 国内自拍视频一区二区三区| 伊人网在线播放| 久久久久久久久久久妇女| 激情婷婷久久| 老鸭窝毛片一区二区三区| 蜜臀av在线播放一区二区三区 | 欧美~级网站不卡| 国产真实久久| 亚洲综合不卡| 日韩av网站在线观看| 国产日韩在线观看视频| 成人午夜网址| 在线国产一区| 综合日韩在线| 国产精品久久久久77777丨| 四虎国产精品免费观看| 国户精品久久久久久久久久久不卡| 亚洲国产日韩欧美在线| 老牛国产精品一区的观看方式| 日韩在线观看一区二区| 国产精品欧美三级在线观看| 精品国产网站| 夜夜精品视频| 日本色综合中文字幕| 国产精品日本一区二区三区在线| 国产成人精品一区二区三区在线| 久久狠狠婷婷| 视频一区在线播放| 久久国产婷婷国产香蕉| 97精品视频在线看| 香蕉精品999视频一区二区| 88久久精品| 电影亚洲精品噜噜在线观看| 综合激情网站| 久久久久久久欧美精品| 国产一区福利| 国产精品婷婷| 国产美女精品视频免费播放软件| 精品不卡一区| 国产精品日韩| 国产成人1区| 先锋亚洲精品| 成人午夜网址| 日韩欧美另类中文字幕| 91综合网人人| 日本在线视频一区二区| 欧洲av不卡| 日韩高清国产一区在线| 国产精品字幕| 国产精品一区毛片| 亚洲经典在线| 国产一区二区三区不卡视频网站| 伊人久久亚洲热| 国产精品激情电影| 婷婷激情综合| 欧美黑人巨大videos精品| 欧美专区18| 国产粉嫩在线观看| 午夜久久av | 久久影院一区二区三区| 日韩一区二区久久| 国产一区二区三区不卡视频网站 | 老司机精品久久| 国产白浆在线免费观看| 日本在线一区二区三区| 中文字幕在线视频网站| 亚洲tv在线| 久久国产日韩| 美女高潮久久久| 高清不卡一区| 69精品国产久热在线观看| 国产一区91| 日本激情一区| 日本天堂一区| 中文久久精品| 97国产精品| 国产欧美激情| 久久一二三区| 久久视频一区| 久久精品九色| 日韩欧美在线精品| 亚洲作爱视频| 日韩一区二区在线免费| 国产精品22p| 91精品尤物| 日本高清久久| 亚洲精品黄色| 欧美日韩中文一区二区| 国产+成+人+亚洲欧洲在线| 18国产精品| 日韩一区中文| 亚洲午夜久久| 首页亚洲欧美制服丝腿| 国产视频久久| 五月综合激情| 亚洲精品在线影院| 岛国av在线网站| 高清一区二区三区| 久久av免费看| 欧美激情麻豆| 麻豆成人在线观看| 国产精品对白| 久久精品xxxxx| 久久不卡日韩美女| 欧美日韩xxxx| 四虎国产精品免费久久| 亚洲一区免费| 亚洲经典在线| 欧美日韩激情在线一区二区三区| 久久激情中文| 亚洲成人av观看| 欧美日韩精品一区二区三区在线观看| 日韩在线电影| 欧美一区影院| 久久国产精品色av免费看| 欧美日韩va| 国产欧美日韩一区二区三区四区 | 今天的高清视频免费播放成人| 久久高清精品| 夜久久久久久| 视频一区日韩精品| 久久国产视频网| 精品三级av| 香蕉视频亚洲一级| 午夜欧美精品| 伊人久久大香伊蕉在人线观看热v| 亚洲网址在线观看| 欧美日韩亚洲一区二区三区在线| 国产精品红桃| 国产91欧美| 国户精品久久久久久久久久久不卡| 五月综合激情| 亚洲精品乱码| 国产精久久一区二区| 日韩不卡一二三区| 日韩国产一区二| 国产欧美一区二区三区国产幕精品 | 欧美亚洲国产日韩| 久久99久久久精品欧美| 国产麻豆精品久久| 卡一卡二国产精品| 免费观看亚洲| 国产亚洲高清视频| 青青草国产成人99久久| 国产在视频一区二区三区吞精| 日韩中文视频| 亚洲一区二区日韩| 麻豆一区二区三| 国产日产一区| 欧美日韩精品免费观看视完整| 久久久久久久久久久9不雅视频| 五月天久久网站| 亚洲精品在线二区| 国产精品115| 91亚洲一区| 中日韩男男gay无套| 欧美日韩中出| 不卡一二三区| 在线亚洲国产精品网站| 国产日韩欧美在线播放不卡| 国产精品精品| 日韩中文字幕亚洲一区二区va在线 | 九九在线精品| 日本伊人久久| 欧美国产美女| 蜜臀久久久久久久| 国精品产品一区| 欧美日韩在线网站| 青草av.久久免费一区| 亚洲成a人片| 婷婷视频一区二区三区| 国产美女高潮在线| 免费在线观看一区二区三区| 精品72久久久久中文字幕| 久久国产亚洲| 中文字幕免费一区二区| 精品国产麻豆| 久热精品在线| 给我免费播放日韩视频| 免费成人在线影院| 黄色网一区二区| 亚洲专区视频| 成人日韩av| 亚洲专区视频| 久久久五月天| 国产精品亚洲欧美日韩一区在线| 亚洲手机视频| 日本在线啊啊| 国产情侣一区在线|