婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > mysql IS NULL使用索引案例講解

mysql IS NULL使用索引案例講解

熱門標簽:400電話可以辦理嗎 智能外呼系統復位 大眾點評星級酒店地圖標注 云南電商智能外呼系統價格 臨清電話機器人 高清地圖標注道路 話務外呼系統怎么樣 外東北地圖標注 拉卡拉外呼系統

簡介

mysql的sql查詢語句中使用is null、is not null、!=對索引并沒有任何影響,并不會因為where條件中使用了is null、is not null、!=這些判斷條件導致索引失效而全表掃描。

mysql官方文檔也已經明確說明is null并不會影響索引的使用。

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.

事實上,導致索引失效而全表掃描的通常是因為一次查詢中回表數量太多。mysql計算認為使用索引的時間成本高于全表掃描,于是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');

執行sql查詢時使用is null、is not null,發現依然使用的索引查詢,并沒有出現索引失效的問題。

分析

分析上述現象,則需要詳細了解mysql索引的工作原理以及索引數據結構。下面,分別通過工具解析和直接查看二進制文件兩種方式分別分析mysql索引數據結構。

工具解析

innodb_ruby是一個非常強大的mysql分析工具,可以用來輕松解析mysql的.ibd文件進而深入理解mysql的數據結構。

首先安裝innodb_ruby工具:

yum install -y rubygems ruby-deve
gem install innodb_ruby

innodb_ruby的功能很多,此處我們只需要用來解析mysql的索引結構,因此只需要如下的命令即可。更多的功能和命令詳見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-recurse
ROOT 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-recurse
ROOT NODE #4: 3 records, 38 bytes
  RECORD: (name=:NULL) → (id=2)
  RECORD: (name="cat") → (id=3)
  RECORD: (name="tom") → (id=1)

通過解析工具數據mysql的索引結構可以發現,null值也被儲存到了索引樹中,并且null值被處理成最小的值放在index_name索引樹的最左側。

二進制文件

找到user_info表對應的物理文件user_info.ibd,通過軟件例如UltraEdit打開,直接定位到第5個數據頁(mysql默認一個數據頁占用16KB)。

如圖,這些二進制數據就是index_name索引對應的索引頁數據,只挑選其中的索引記錄,展開如下:

最小記錄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的值:tom
80 00 00 01 			RowID:主鍵id的值為1

ID為2的索引0x0001008c

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

ID為3的索引0x00010097

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

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

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

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

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

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

誤解原因

為何大眾誤解認為is null、is not null、!=這些判斷條件會導致索引失效而全表掃描呢?

導致索引失效而全表掃描的通常是因為一次查詢中回表數量太多。mysql計算認為使用索引的時間成本高于全表掃描,于是mysql寧可全表掃描也不愿意使用索引。使用索引的時間成本高于全表掃描的臨界值可以簡單得記憶為20%左右。

詳細的分析過程可以見筆者的另一篇博客:mysql回表致索引失效。

也就是如果一條查詢語句導致的回表范圍超過全部記錄的20%,則會出現索引失效的問題。而is null、is not null、!=這些判斷條件經常會出現在這些回表范圍很大的場景,然后被人誤解為是這些判斷條件導致的索引失效。

復現索引失效

復現索引失效,只需要回表范圍超過全部記錄的20%,如下插入1000條非null記錄。

delimiter  //
CREATE PROCEDURE init_user_info() 
BEGIN 
	DECLARE indexNo INT;
	SET indexNo = 0;
	WHILE indexNo  1000 DO
		START 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();

此時user_info表中一共有1003條記錄,其中只有1條記錄的name值為null。那么is null判斷語句導致的回表記錄只有1/1003不會超過臨界值,而is not null判斷語句導致的回表記錄有1002/1003遠遠超過臨界值,將出現索引失效的現象。

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

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

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

optimizer tracing輸出的執行計劃可見,該查詢下,使用全表掃描所需要的時間成本為206.9;而使用索引所需要的時間成本為1203.4,遠遠高于全表掃描。因此mysql最終選擇全表掃描而出現索引失效的現象。

{
    "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"
                    }
                }
            }
        }
    ]
}

到此這篇關于mysql IS NULL使用索引案例講解的文章就介紹到這了,更多相關mysql IS NULL使用內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 常用SQL功能語句
  • MySQL/MariaDB中如何支持全部的Unicode
  • SQL insert into語句寫法講解
  • SQL寫法--行行比較

標簽:阿里 無錫 揚州 溫州 福州 山西 定西 三明

巨人網絡通訊聲明:本文標題《mysql IS NULL使用索引案例講解》,本文關鍵詞  mysql,NULL,使用,索引,案例,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《mysql IS NULL使用索引案例講解》相關的同類信息!
  • 本頁收集關于mysql IS NULL使用索引案例講解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    国产乱理伦片在线观看夜一区| 久久精品国产免费看久久精品| 中文字幕欧美三区| 亚洲自拍另类综合| 国产精品中文字幕欧美| 色婷婷亚洲一区二区三区| 欧美zozo另类异族| 亚洲国产wwwccc36天堂| 97se亚洲国产综合自在线不卡 | 日韩亚洲欧美综合| 亚洲视频在线一区观看| 国产精品中文有码| 精品国产123| 日韩高清不卡在线| 欧美亚洲国产一区二区三区| 亚洲国产精品国自产拍av| 激情欧美一区二区| 91精品国产综合久久香蕉麻豆| 一区二区免费在线| 一本色道久久加勒比精品| 欧美高清在线一区二区| 国内精品伊人久久久久影院对白| 欧美卡1卡2卡| 亚洲成人精品一区二区| 色老头久久综合| 亚洲欧美激情小说另类| av中文字幕在线不卡| 久久久一区二区| 韩日av一区二区| 欧美电影免费观看高清完整版在线| 婷婷一区二区三区| 欧美日韩国产综合一区二区| 一区二区欧美国产| 欧美丝袜丝nylons| 日韩国产欧美三级| 91精品久久久久久久99蜜桃 | 香蕉影视欧美成人| 欧美中文字幕一区| 日韩国产精品久久| 欧美大片拔萝卜| 国产自产高清不卡| 欧美韩日一区二区三区四区| 99精品在线免费| 亚洲成人福利片| 91麻豆精品91久久久久同性| 久久99精品国产.久久久久久| 久久免费精品国产久精品久久久久 | 午夜视频一区二区| 欧美久久免费观看| 奇米影视一区二区三区小说| 日韩精品资源二区在线| 国产精一区二区三区| 国产欧美一区二区精品性色| 国产成人在线影院| 亚洲精品免费一二三区| 欧美日本一道本| 精品一区二区三区在线观看国产 | 午夜视频在线观看一区二区| 欧美一区二区三区四区久久| 国产一区在线视频| 国产精品传媒视频| 欧美视频日韩视频在线观看| 国内不卡的二区三区中文字幕| 国产免费久久精品| 色婷婷久久久久swag精品| 免费观看一级特黄欧美大片| 国产日韩三级在线| 欧美日韩一区二区在线观看| 国产激情视频一区二区三区欧美 | 欧美日韩精品欧美日韩精品一| 麻豆久久久久久久| 亚洲人亚洲人成电影网站色| 欧美卡1卡2卡| 91网站在线播放| 久久不见久久见免费视频1| 亚洲男人的天堂在线aⅴ视频| 日韩一级成人av| 97精品视频在线观看自产线路二| 免费高清在线一区| 亚洲视频香蕉人妖| 国产亚洲成av人在线观看导航| 色8久久人人97超碰香蕉987| 国产一区二区电影| 日韩激情一二三区| 一二三四社区欧美黄| 国产精品女主播在线观看| 制服丝袜日韩国产| 91福利在线导航| 国产白丝网站精品污在线入口| 三级一区在线视频先锋| 亚洲狠狠丁香婷婷综合久久久| 国产片一区二区| 久久久91精品国产一区二区精品 | 亚洲免费av观看| 精品国产91洋老外米糕| 欧美一级理论片| 欧美视频三区在线播放| 日本久久一区二区三区| 成人免费av网站| 成人三级伦理片| 国产精品中文有码| 国产一区二区三区精品视频| 久久疯狂做爰流白浆xx| 日韩av电影免费观看高清完整版| 尤物视频一区二区| 国产精品电影一区二区| 国产精品初高中害羞小美女文| 26uuu成人网一区二区三区| 精品福利一区二区三区免费视频| 在线播放欧美女士性生活| 欧美色图在线观看| 欧美精品一二三| 91精品国产一区二区三区香蕉| 欧美日韩国产另类一区| 欧美高清激情brazzers| 欧美精品tushy高清| 91精品视频网| 精品成人a区在线观看| 日韩美女主播在线视频一区二区三区 | 欧洲一区在线电影| 欧美视频一区二| 欧美一区二区视频在线观看2020 | 亚洲男人的天堂网| 一级日本不卡的影视| 亚洲成人av免费| 免费成人av在线| 国产一区二区三区电影在线观看| 国产麻豆9l精品三级站| 成人免费黄色大片| 色婷婷激情一区二区三区| 欧美专区日韩专区| 日韩美女主播在线视频一区二区三区| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 精品福利二区三区| 国产农村妇女毛片精品久久麻豆| 亚洲色图视频网站| 日本不卡中文字幕| 国产传媒欧美日韩成人| 91麻豆自制传媒国产之光| 欧美日韩欧美一区二区| 2024国产精品| 亚洲另类在线制服丝袜| 婷婷久久综合九色综合伊人色| 国内成人精品2018免费看| 一本大道久久精品懂色aⅴ| 欧美日韩电影在线播放| 久久亚洲综合色一区二区三区| 亚洲欧美一区二区久久| 免费看精品久久片| 丁香网亚洲国际| 7777精品伊人久久久大香线蕉超级流畅 | 在线一区二区三区四区五区| 555夜色666亚洲国产免| 国产日韩欧美一区二区三区综合| 一个色综合网站| 国产成a人无v码亚洲福利| 欧美日韩第一区日日骚| 亚洲国产高清在线| 美美哒免费高清在线观看视频一区二区 | 欧美亚洲动漫制服丝袜| 久久亚洲捆绑美女| 亚洲风情在线资源站| 成人综合婷婷国产精品久久| 91精品国产91综合久久蜜臀| 亚洲欧美怡红院| 国产乱妇无码大片在线观看| 51午夜精品国产| 一区二区不卡在线播放 | 久久综合九色综合97_久久久| 一区二区三区在线看| 国产精品91一区二区| 欧美一区二区三区在线观看视频| 亚洲视频一二三区| 成人免费毛片aaaaa**| 欧美成人官网二区| 天天操天天色综合| 色菇凉天天综合网| 国产精品美女久久久久aⅴ国产馆| 青青草伊人久久| 欧美日韩国产欧美日美国产精品| 一区二区三区在线免费视频| 99视频国产精品| 中文字幕av在线一区二区三区| 韩国av一区二区三区在线观看| 69久久99精品久久久久婷婷| 亚洲第一精品在线| 欧美日韩三级一区| 午夜日韩在线电影| 欧美高清视频不卡网| 亚洲成人精品一区| 9191成人精品久久| 青椒成人免费视频| 欧美日韩免费电影| 视频一区视频二区在线观看| 欧美理论在线播放| 免费成人结看片| 日韩欧美在线不卡| 国产一区二区主播在线| 欧美精品一区二区久久久| 国产一区二区三区在线观看精品|