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

 

作者 admin

百度广告效果展示