MySQL索引优化(索引单表优化案例)

1、单表查询优化

建表SQL

CREATE TABLE IF NOT EXISTS `article` (
`id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
`author_id` INT(10) UNSIGNED NOT NULL,
`category_id` INT(10) UNSIGNED NOT NULL,
`views` INT(10) UNSIGNED NOT NULL,
`comments` INT(10) UNSIGNED NOT NULL,
`title` VARBINARY(255) NOT NULL,
`content` TEXT NOT NULL
);

INSERT INTO `article`(`author_id`, `category_id`, `views`, `comments`, `title`, `content`) VALUES
(1, 1, 1, 1, ‘1‘, ‘1‘),
(2, 2, 2, 2, ‘2‘, ‘2‘),
(1, 1, 3, 3, ‘3‘, ‘3‘);

SELECT * FROM article;

案例

#查询 category_id 为1 且 comments 大于 1 的情况下,views 最多的 article_id。

执行sql:

EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT 1;

#结论:很显然,type 是 ALL,即最坏的情况。Extra 里还出现了 Using filesort,也是最坏的情况。优化是必须的。

查询索引:show index from article;

#开始优化:
# 1.1 新建索引+删除索引
#ALTER TABLE `article` ADD INDEX idx_article_ccv ( `category_id` , `comments`, `views` );
create index idx_article_ccv on article(category_id,comments,views);
DROP INDEX idx_article_ccv ON article

# 1.2 第2次EXPLAIN
EXPLAIN SELECT id,author_id FROM `article` WHERE category_id = 1 AND comments >1 ORDER BY views DESC LIMIT 1;

#结论:
#type 变成了 range,这是可以忍受的。但是 extra 里使用 Using filesort 仍是无法接受的。
#但是我们已经建立了索引,为啥没用呢?
#这是因为按照 BTree 索引的工作原理,
# 先排序 category_id,
# 如果遇到相同的 category_id 则再排序 comments,如果遇到相同的 comments 则再排序 views。
#当 comments 字段在联合索引里处于中间位置时,
#因comments > 1 条件是一个范围值(所谓 range),
#MySQL 无法利用索引再对后面的 views 部分进行检索,即 range 类型查询字段后面的索引无效。

# 1.3 删除第一次建立的索引
DROP INDEX idx_article_ccv ON article;

# 1.4 第2次新建索引
#ALTER TABLE `article` ADD INDEX idx_article_cv ( `category_id` , `views` ) ;
create index idx_article_cv on article(category_id,views);

# 1.5 第3次EXPLAIN
EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT 1;

#结论:可以看到,type 变为了 ref,Extra 中的 Using filesort 也消失了,结果非常理想。

原文地址:https://www.cnblogs.com/116970u/p/10985964.html

时间: 2024-10-27 01:48:55

MySQL索引优化(索引单表优化案例)的相关文章

MySQL 单表优化

一.表字段优化 1.整数类型尽量使用 TINYINT.SMALLINT.MEDIUM_INT 而不是INT,非负数要加上UNSIGNED 2.VARCHAR的长度分配要合理,不要过大 3.时间字段不超过2037年的使用TIMESTAMP而不是DATETIME 4.单表字段最好不要超过20 5.字段设定默认值,不要有NULL字段 6.IP值存储时最好转成整型 二.表索引优化 1.合理建索引,根据WHERE 和 ORDER BY 可能涉及的列建立 2.SQL 语句尽量避免在WHERE 子句中判断 N

mysql四-1:单表查询

一.单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二.关键字的执行优先级(重点) 1.from  库.表--找到表 2.where  条件--按照where指定的约束条件,去表中取出一条条记录 3.group by  分组条件--对取出的一条条记录分组,如果没有group by,整体作为一组 4.having  过滤--将分组的结果进行过滤 5.selec

如何用Percona XtraBackup进行MySQL从库的单表备份和恢复【转】

前提 应该确定采用的是单表一个表空间,否则不支持单表的备份与恢复. 在配置文件里边的mysqld段加上 innodb_file_per_table = 1 环境说明: 主库:192.168.0.1 从库1:192.168.0.2 从库2:192.168.0.3 备份工具 : Percona xtrabackup version 2.4.8 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 97330f7) 在主库上创建chenfe

(七)MySQL数据操作DQL:单表查询

(1)单表查询 1)环境准备 mysql> CREATE TABLE company.employee5( id int primary key AUTO_INCREMENT not null, name varchar(30) not null, sex enum('male','female') default 'male' not null, hire_date date not null, post varchar(50) not null, job_description varcha

MySQL数据库篇之单表查询

主要内容: 一.单表查询的语法 二.关键字的执行优先级 三.简单查询 四.where约束 五.分组查询 group by 六.having过滤 七.查询排序 order by 八.限制查询的记录数 limit 九.使用正则表达式查询 1?? 单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 2??  关键字的执行优先级 重点中的重点:关键字的执行优先级(从上至

MySql(六)单表查询

一.单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 二.关键字的执行优先级(重点) 重点中的重点:关键字的执行优先级fromwheregroup byhavingselectdistinctorder bylimit 1.找到表:from 2.拿着where指定的约束条件,去文件/表中取出一条条记录 3.将取出的一条条记录进行分组group by,如果没有g

Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查

一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process using '"' #可以直接用 python3 -m pip 代替 pip3 #这个问题是pip3 版本过低直接在cmd中执行 python3 -m pip install --upgrade pip 更新pip3 # 在指定解释器环境下安装django 1.11.9 # 在真实python3环境

MySQL简单查询和单表查询

MySQL记录操作 概览 MySQL数据操作: DML 在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 使用INSERT实现数据的插入 UPDATE实现数据的更新 使用DELETE实现数据的删除 使用SELECT查询数据以及. 插入数据insert 1. 插入完整数据(顺序插入) 语法一: INSERT INTO 表名(字段1,字段2,字段3-字段n) VALUES(值1,值2,值3-值n); 语法二: INSERT INTO 表名 VALUES (值1,值2,值

mysql 数据库 IV(单表查询)

1.今日内容 单表查询语法 select distinct 字段1,字段2... from 表名 where 条件 group by 字段 having 筛选 order by 字段 limit 限制条数 关键字执行的优先级 from # 找到表 where # 拿着where指定的约束条件,去文件/表中取出一条条记录 group by # 将取出来的数据进行group by,如果没有group by,则整体做为一组 select distinct #执行select-去重 having #将分