MySQL中的InnoDB單表訪問過程
1、背景
mysql通過查詢條件查詢到結(jié)果的過程就叫訪問方法,一條查詢語句的訪問方法有很多種,接下來我們就來講一下各種訪問方法。
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、訪問類型
【1】const
通過主鍵索引或者唯一索引查詢一條記錄的方法就為const,可以通過explain關(guān)鍵字來看查詢語句的訪問方式,通過主鍵查詢示例:
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字段就是訪問方式,我們再看看通過唯一索引查詢的示例:
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ìn)行等值匹配時(shí),訪問類型就為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ìn)行等值匹配時(shí),又想把值為NULL的查詢出來,這種查詢類型就為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í)候就會將組合索引葉子節(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
對主鍵索引所在的葉子節(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)化器會將我們的查詢條件進(jìn)行優(yōu)化,我們可以通過explain關(guān)鍵字來查看單表查詢的訪問方式。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Mysql主從三種復(fù)制模式(異步復(fù)制,半同步復(fù)制,組復(fù)制)
這篇文章主要介紹了Mysql主從三種復(fù)制模式(異步復(fù)制,半同步復(fù)制,組復(fù)制),MySQL異步復(fù)制是主從復(fù)制過程中默認(rèn)的復(fù)制模式,下文簡單介紹,感興趣的朋友可以參考一下2022-08-08Mysql update多表聯(lián)合更新的方法小結(jié)
這篇文章主要介紹了Mysql update多表聯(lián)合更新的方法小結(jié),通過實(shí)例代碼給大家介紹了mysql多表關(guān)聯(lián)update的語句,感興趣的朋友跟隨小編一起看看吧2020-02-02MySQL錯(cuò)誤“Data?too?long”的原因、解決方案與優(yōu)化策略
MySQL作為重要的數(shù)據(jù)庫系統(tǒng),在數(shù)據(jù)插入時(shí)可能遇到“Data?too?long?for?column”錯(cuò)誤,本文探討了該錯(cuò)誤的原因、解決方案及預(yù)防措施,如調(diào)整字段長度、使用TEXT類型等,旨在優(yōu)化數(shù)據(jù)庫設(shè)計(jì),提升性能和用戶體驗(yàn),需要的朋友可以參考下2024-09-09MySQL8.0實(shí)現(xiàn)窗口函數(shù)計(jì)算同比環(huán)比
本文主要介紹了MySQL8.0實(shí)現(xiàn)窗口函數(shù)計(jì)算同比環(huán)比,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06MySQL實(shí)現(xiàn)查詢某個(gè)字段含有字母數(shù)字的值
這篇文章主要介紹了MySQL實(shí)現(xiàn)查詢某個(gè)字段含有字母數(shù)字的值方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07