t_flm电影表(100万行)
创建数据库:
DROP
TABLE
IF EXISTS t_film
;
CREATE
TABLE t_film(
id INTEGER
AUTO_INCREMENT
PRIMARY
KEY
,
score DECIMAL
(2,1) NOT
NULL COMMENT
‘评分’,
release_date DATE
NOT
NULL COMMENT
‘发行日期’,
film_name VARCHAR
(20) NOT
NULL COMMENT
‘电影名称’,
introduction VARCHAR
(30) NOT
NULL COMMENT
‘简介’
);
创建1000000条测试数据:
#删除存储过程
DROP
PROCEDURE IF EXISTS proc_t_film;
#创建存储过程
DELIMITER
$$
CREATE
PROCEDURE
proc_t_film(total
int)
BEGIN
DECLARE
1 INTEGER
DEFAULT
1;
START
TRANSACTION
;
WHILE
i<=total
DO
INSERT
INTO
t_fi1m(score, release_date, fi1m_name, introduction)
VALUES (
ROUND
(RAND
() * 9.9, 1),
DATE_ADD
(NOW
(),
INTERVAL
FLOOR
(RAND
() * 10000) DAY),
CONCAT
(‘fi1m_name’, 1),
CONCAT
(‘introduction’, i) );
SET
=1 + 1;
END
WHILE
;
COMNIT
;
END
$$
DELIMITER
;
#执行存储过程
CALL
proc_t_fi1m(1000000);
测试数据内容如下:
id score release_date fim_name introduction 1 4.9 2028-11-29 fim_name1 introduction1 2 5.6 2027-12-02 fim_name2 introduction2 3 1.8 2034-05-21 fim_name3 introduction3
查询要求:查询电影表中第N页数据,每页20条记录,按照评分降序进行排序, 查询字段为评分(score) , 发行日期(release_date) ,电影名称(film_name):
浅分表
SELECT
score, release_date, fi1m_name FROM
t_fi1m ORDER
BY score DESC LIMIT
5, 20;
深分表
SELECT
score, release_date, fi1m_name FROM
t_fi1m ORDER
BY score DESC LIMIT
90000, 20;
explain分析:
优化1:索引
Order By字段加单列索引
$ ALTER
TABLE
t_film ADD INDEX idx_score (score);
从执行效果上可以看出,浅分页得到了一个优化,而对于深分页来说基本没有效果。
原因分析:
“type=index”。说明是“全索引扫描”。
“LIMIT 5,20”,将会扫描25行数据,接着丢弃掉前5条,根据保留的20条数据。然后[回表查询]“release_date”、“fi1m_name”的最终结果。
这时候回表的成本将>自己排序的成本。优化器会选择不走索引。
深分表(强制走索引)
SELECT
score, release_date, fi1m_name FROM
t_fi1m force index(idx_score) ORDER
BY score DESC LIMIT
90000, 20;
在测试过程中发现,当迁移量在4000-5000之前,mysql都会走索引,超出就走全表扫描。
优化2:解决深分页问题
方法一: Order By和Select字段加联合索引
ALTER
TABLE t_film ADD INDEX idx_score_date_name (score, release_date, film_name);
注意:score要在首位
走索引消除了Using Filesort,并使用了覆盖索引
方法二: Order By字段加索引并手动回表
SELECT
score, release_date,film_name FROM t_film a join,
(SELECT
id FROM t_ fi1m ORDER BY score DESC LIMIT 900000,20)b on a.id = b.id;
对比方法一:
●不需要添加联合索引
●不会随着查询字段的增加而影响性能
手动回表的应用一解决由于回表性能消耗过大而不走索引的问题
注意:当子查询结果集太大时,手动回表的性能反而比不上全查询
参考视频:https://www.bilibili.com/video/BV198411F7hx/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=3790692eb971db4659c7e5f6dc3e29fc