MySQL性能优化
Posted 听歌敲代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL性能优化相关的知识,希望对你有一定的参考价值。
一、order by产生using filesort详解
1.首先建表和索引
/*课程表*/ create table course( id int primary key auto_increment,/* 主键自增*/ title varchar(50) not null,/* 标题*/ category_id int not null,/* 属于哪个类目*/ school_id int not null,/* 属于哪个学校*/ buy_times int not null,/* 购买次数*/ browse_times int not null/* 浏览次数*/ ); insert into course(title,category_id,school_id,buy_times,browse_times) values(‘java课程‘,1,1,800,8680); insert into course(title,category_id,school_id,buy_times,browse_times) values(‘android课程‘,2,1,400,8030); insert into course(title,category_id,school_id,buy_times,browse_times) values(‘mysql课程‘,3,2,200,2902); insert into course(title,category_id,school_id,buy_times,browse_times) values(‘oracle课程‘,2,2,100,6710); insert into course(title,category_id,school_id,buy_times,browse_times) values(‘C#课程‘,1,3,620,2890); insert into course(title,category_id,school_id,buy_times,browse_times) values(‘PS课程‘,4,4,210,4300); insert into course(title,category_id,school_id,buy_times,browse_times) values(‘CAD课程‘,5,1,403,6080); /*在category_id和buy_times上建立组合索引*/ create index idx_cate_buy on course(category_id,buy_times);
2.order by 会产生 using filesort的有哪些?
(1)explain select id from course where category_id>1 order by category_id;
根据最左前缀原则,order by后面的的category_id会用到组合索引
(2)explain select id from course where category_id>1 order by category_id,buy_times;
根据最左前缀原则,order by后面的的category_id buy_times会用到组合索引,因为索引就是这两个字段
(3)explain select id from course where category_id>1 order by buy_times;
根据最左前缀原则,order by后面的字段是缺少了最左边的category_id,所以会产生 using filesort
(4)explain select id from course where category_id>1 order by buy_times,category_id;
order by后面的字段顺序不符合组合索引中的顺序,所以order by后面的不会走索引,即会产生using filesort
(5)explain select id from course order by category_id;
根据最左前缀原则,order by后面存在索引中的最左列,所以会用到索引
(6)explain select id from course order by buy_times;
根据最左前缀原则,order by后面的字段 没有索引中的最左列的字段,所以不会走索引,会产生using filesort
(7)explain select id from course where buy_times > 1 order by buy_times;
根据最左前缀原则,order by后面的字段 没有索引中的最左列的字段,所以不会走索引,会产生using fillesort
(8)explain select id from course where buy_times > 1 order by category_id;
根据最左前缀原则,order by后面的字段存在于索引中最左列,所以会走索引
(9)explain select id from course order by buy_times desc,category_id asc;
根据最最左前缀原则,order by后面的字段顺序和索引中的不符合,则会产生using filesort
(10)explain select id from course order by category_id desc,buy_times asc;
这一条虽然order by后面的字段和索引中字段顺序相同,但是一个是降序,一个是升序,所以也会产生using filesort,同时升序和同时降序就不会产生using filesort了
二、in和exists哪个性能更优
sql脚本:
/*建库*/ create database testdb6; use testdb6; /* 用户表 */ drop table if exists users; create table users( id int primary key auto_increment, name varchar(20) ); insert into users(name) values (‘A‘); insert into users(name) values (‘B‘); insert into users(name) values (‘C‘); insert into users(name) values (‘D‘); insert into users(name) values (‘E‘); insert into users(name) values (‘F‘); insert into users(name) values (‘G‘); insert into users(name) values (‘H‘); insert into users(name) values (‘I‘); insert into users(name) values (‘J‘); /* 订单表 */ drop table if exists orders; create table orders( id int primary key auto_increment,/*订单id*/ order_no varchar(20) not null,/*订单编号*/ title varchar(20) not null,/*订单标题*/ goods_num int not null,/*订单数量*/ money decimal(7,4) not null,/*订单金额*/ user_id int not null /*订单所属用户id*/ )engine=myisam default charset=utf8 ; delimiter $$ drop procedure batch_orders $$ /* 存储过程 */ create procedure batch_orders(in max int) begin declare start int default 0; declare i int default 0; set autocommit = 0; while i < max do set i = i + 1; insert into orders(order_no,title,goods_num,money,user_id) values (concat(‘NCS-‘,floor(1 + rand()*1000000000000 )),concat(‘订单title-‘,i),i%50,(100.0000+(i%50)),i%10); end while; commit; end $$ delimiter ; /*插入1000万条订单数据*/ call batch_orders(10000000); /*插入数据的过程根据机器的性能 花费的时间不同,有的可能3分钟,有的可能10分钟*/
上面的sql中 订单表中(orders) 存在user_id,而又有用户表(users),所以我们用orders表中user_id和user表中的id 来in 和 exists。
结果分析
1.where后面是小表
(1)select count(1) from orders o where o.user_id in(select u.id from users u);
(2)select count(1) from orders o where exists (select 1 from users u where u.id = o.user_id);
三、慢查询
四、锁机制
以上是关于MySQL性能优化的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 数据库 Schema 设计的性能优化①:高效的模型设计