mysql延迟关联为什么快_MySQL 覆盖索引与延迟关联详解
本期來談談覆蓋索引與延遲關聯。在此之前,我們先簡單建立一個訂單表 Orders 用于舉例說明。表中共包含 3 個字段:
id
int
product_id
name
CREATE
TABLE
`orders`
`id`
int
10
NOT
NULL
COMMENT
'訂單?ID'
`product_id`
int
10
DEFAULT
NULL
COMMENT
'商品?ID'
`name`
varchar
255
CHARACTER
SET
COLLATE
DEFAULT
NULL
COMMENT
'訂單名稱'
KEY
`id`
KEY
`product_idx`
`product_id`
USING
ENGINE
InnoDB
DEFAULT
CHARSET
COLLATE
覆蓋索引
什么是覆蓋索引?
根據索引
不包含
覆蓋索引
MyISAM
product_id
SELECT product_id FROM orders
EXPLAIN
SELECT
FROM
----+-------------+--------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
----+-------------+--------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
----+-------------+--------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
set
0.00
id
SELECT id, product_id FROM orders WHERE product_id = 1
product_id
product_id = 1
通過該子結點指針讀取磁盤上的數據行
id
由于 MyISAM 的葉子結點存儲著指向數據行的指針,該查詢多了一步回表操作,無法使用覆蓋索引。
EXPLAIN
SELECT
id
FROM
WHERE
1
----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
set
0.00
MyISAM 索引結構
InnoDB
二級索引的葉子結點保存著行的主鍵值
InnoDB 二級索引的葉子結點包含行主鍵值
SELECT id, product_id FROM orders WHERE product_id = 1
EXPLAIN
SELECT
id
FROM
WHERE
1
----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+
----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+
----+-------------+--------+------------+------+---------------+-------------+---------+-------+------+----------+-------------+
set
0.01
Extra
Using index
product_id
product_id = 1
id
查詢軌跡并未進行回表取值。
延遲關聯
deferred join
在查詢的第一階段 MySQL 使用覆蓋索引,再通過該覆蓋索引查詢到的結果到外層查詢匹配需要的所有列值。
這樣說有些抽象,我們來看看下面的例子。
用延遲關聯優化分頁(LIMIT)
LIMIT
LIMIT 10000, 20
EXPLAIN
SELECT
FROM
LIMIT
10000
20
----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
盡可能使用索引覆蓋掃描,而不是查詢所有列
EXPLAIN
SELECT
FROM
AS
JOIN
SELECT
id
FROM
LIMIT
10000
20
AS
ON
----+-------------+------------+------------+-------+---------------+-------------+---------+------------+------+----------+-------------+
----+-------------+------------+------------+-------+---------------+-------------+---------+------------+------+----------+-------------+
----+-------------+------------+------------+-------+---------------+-------------+---------+------------+------+----------+-------------+
這樣一來,MySQL 在 SQL 語句的「內層」進行掃描時使用了覆蓋索引,「外層」再通過索引樹找到相關的數據行,直接減少了掃描的數據量。
總結
只需掃描索引,無須回表
deferred join
參考資料
《高性能 MySQL》
[1]
參考資料
[1]
https://book.douban.com/subject/23008813/
更多閱讀
5分鐘掌握在 Cython 中使用 C++
5 分鐘掌握 Python 中常見的配置文件
5 分鐘掌握 Python 中的 Hook 鉤子函數
點擊下方閱讀原文加入
社區會員
總結
以上是生活随笔為你收集整理的mysql延迟关联为什么快_MySQL 覆盖索引与延迟关联详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简单实现网络验证_电脑计算机编程入门教程
- 下一篇: GMapping原理分析