MySQL中的InnoDB單表訪問(wèn)過(guò)程
1、背景
mysql通過(guò)查詢條件查詢到結(jié)果的過(guò)程就叫訪問(wèn)方法,一條查詢語(yǔ)句的訪問(wèn)方法有很多種,接下來(lái)我們就來(lái)講一下各種訪問(wèn)方法。
2、環(huán)境
創(chuàng)建表:
mysql> CREATE TABLE test2
-> (
-> id INT AUTO_INCREMENT PRIMARY KEY,
-> str1 VARCHAR(255),
-> str2 VARCHAR(255),
-> str3 CHAR(5),
-> str4 VARCHAR(255),
-> str5 CHAR(10),
-> INDEX idx_str1 (str1),
-> UNIQUE INDEX idx_str3 (str3),
-> INDEX idx_str4_str5 (str4, str5)
-> ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
Query OK, 0 rows affected, 1 warning (0.03 sec)
插入100條數(shù)據(jù):
mysql> INSERT INTO test2 (str1, str2, str3, str4, str5) VALUES
-> ('value1', 'data1', 'abc', 'value4_1', 'value5_1'),
-> ('value2', 'data2', 'def', 'value4_2', 'value5_2'),
-> ...
-> ('value99', 'data99', 'yz91', 'value4_99', 'value5_99'),
-> ('value100', 'data100', 'yz92', 'value4_100', 'value5_100');
Query OK, 100 rows affected (0.02 sec)
Records: 100 Duplicates: 0 Warnings: 0
3、訪問(wèn)類型
【1】const
通過(guò)主鍵索引或者唯一索引查詢一條記錄的方法就為const,可以通過(guò)explain關(guān)鍵字來(lái)看查詢語(yǔ)句的訪問(wèn)方式,通過(guò)主鍵查詢示例:
mysql> explain select * from test2 where id = 3; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | test2 | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
type字段就是訪問(wèn)方式,我們?cè)倏纯赐ㄟ^(guò)唯一索引查詢的示例:
mysql> explain select * from test2 where str3 = 'abc'; +----+-------------+-------+------------+-------+---------------+----------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+----------+---------+-------+------+----------+-------+ | 1 | SIMPLE | test2 | NULL | const | idx_str3 | idx_str3 | 16 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+-------+---------------+----------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
【2】ref
使用普通二級(jí)索引進(jìn)行等值匹配時(shí),訪問(wèn)類型就為ref,示例如下:
mysql> explain select * from test2 where str1 = 'value7'; +----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+ | 1 | SIMPLE | test2 | NULL | ref | idx_str1 | idx_str1 | 767 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.01 sec)
【3】ref_or_null
二級(jí)索引進(jìn)行等值匹配時(shí),又想把值為NULL的查詢出來(lái),這種查詢類型就為ref_or_null,先把上面插入的數(shù)據(jù)部分記錄的str1字段改為NULL,sql如下:
mysql> update test2 set str1 = NULL where id in (3, 6, 8, 9, 34, 78, 89); Query OK, 7 rows affected (0.01 sec) Rows matched: 7 Changed: 7 Warnings: 0
再看查詢類型:
mysql> explain select * from test2 where str1 = 'value7' or str1 = null;
+----+-------------+-------+------------+-------------+---------------+----------+---------+-------+------+----------+--------
---------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
|
+----+-------------+-------+------------+-------------+---------------+----------+---------+-------+------+----------+--------
---------------+
| 1 | SIMPLE | test2 | NULL | ref_or_null | idx_str1 | idx_str1 | 768 | const | 2 | 100.00 | Using i
ndex condition |
+----+-------------+-------+------------+-------------+---------------+----------+---------+-------+------+----------+--------
---------------+
1 row in set, 1 warning (0.00 sec)
【4】range
顧名思義范圍查詢就是range,示例如下:
mysql> explain select * from test2 where id > 2 and id < 7; +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ | 1 | SIMPLE | test2 | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 4 | 100.00 | Using where | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec)
【5】index
使用組合索引中非最左邊作為查詢條件時(shí),并且查詢的字段不需要回表,這個(gè)時(shí)候就會(huì)將組合索引葉子節(jié)點(diǎn)全部掃描一遍,這種查詢方式就叫index,示例如下:
mysql> explain select str4, str5 from test2 where str5 = 'value5_15';
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+----------
----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
|
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+----------
----------------+
| 1 | SIMPLE | test2 | NULL | index | idx_str4_str5 | idx_str4_str5 | 799 | NULL | 100 | 10.00 | Using whe
re; Using index |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+----------
----------------+
1 row in set, 1 warning (0.00 sec)
【6】all
對(duì)主鍵索引所在的葉子節(jié)點(diǎn)進(jìn)行全表掃描就叫all,示例如下:
mysql> explain select * from test2; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ | 1 | SIMPLE | test2 | NULL | ALL | NULL | NULL | NULL | NULL | 100 | 100.00 | NULL | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
4、總結(jié)
mysql中優(yōu)化器會(huì)將我們的查詢條件進(jìn)行優(yōu)化,我們可以通過(guò)explain關(guān)鍵字來(lái)查看單表查詢的訪問(wèn)方式。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL 8.0 驅(qū)動(dòng)與阿里druid版本兼容問(wèn)題解決
MySQL 8.0 驅(qū)動(dòng)與阿里druid版本不兼容會(huì)導(dǎo)致有報(bào)錯(cuò)問(wèn)題,本文就詳細(xì)的介紹一下解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下2021-07-07
Mysql中報(bào)錯(cuò)函數(shù)floor()函數(shù)和rand()函數(shù)的配合使用及原理詳解
在項(xiàng)目中的SQL語(yǔ)句中遇到幾個(gè)數(shù)值處理函數(shù),看著有些懵,就小小的總結(jié)一下,這篇文章主要給大家介紹了關(guān)于Mysql中報(bào)錯(cuò)函數(shù)floor()函數(shù)和rand()函數(shù)的配合使用及原理的相關(guān)資料,需要的朋友可以參考下2022-07-07
Mysql數(shù)據(jù)庫(kù)自增id、uuid與雪花id詳解
在mysql中設(shè)計(jì)表的時(shí)候,mysql官方推薦不要使用uuid或者不連續(xù)不重復(fù)的雪花id(long形且唯一),而是推薦連續(xù)自增的主鍵id,這篇文章主要給大家介紹了關(guān)于Mysql數(shù)據(jù)庫(kù)自增id、uuid與雪花id的相關(guān)資料,需要的朋友可以參考下2023-02-02
MySQL數(shù)據(jù)類型與表操作全指南(?從基礎(chǔ)到高級(jí)實(shí)踐)
本文詳解MySQL數(shù)據(jù)類型分類(數(shù)值、日期/時(shí)間、字符串)及表操作(創(chuàng)建、修改、維護(hù)),涵蓋優(yōu)化技巧如數(shù)據(jù)類型選擇、備份、分區(qū),強(qiáng)調(diào)規(guī)范設(shè)計(jì)與實(shí)際應(yīng)用結(jié)合,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2025-08-08
MySQL查看每個(gè)分區(qū)的數(shù)據(jù)量的查詢方法
在MySQL中,分區(qū)表是一種將數(shù)據(jù)分割成更小、更易管理的部分的方法,通過(guò)分區(qū),可以顯著提高查詢性能和數(shù)據(jù)管理效率,在實(shí)際應(yīng)用中,了解每個(gè)分區(qū)中的數(shù)據(jù)量有助于優(yōu)化和監(jiān)控?cái)?shù)據(jù)庫(kù)性能,本文將介紹如何查看MySQL中每個(gè)分區(qū)的數(shù)據(jù)量,需要的朋友可以參考下2025-07-07
MySQL數(shù)據(jù)類型和常用字段屬性總結(jié)
這篇文章主要介紹了MySQL數(shù)據(jù)類型和常用字段屬性總結(jié),本文總結(jié)了日期和時(shí)間數(shù)據(jù)類型、數(shù)值數(shù)據(jù)類型、字符串?dāng)?shù)據(jù)類型等,需要的朋友可以參考下2014-09-09

