索引测试
- 通过存储过程往数据库中插入300w 条数据
- 分别测试使用索引和没有使用索引的情况下,where 查询的一个效率对比。
-- 创建表
DROP TABLE IF EXISTS person;
CREATE TABLE person(
PID int(11) auto_increment comment '编号',
PNAME varchar(50) comment '姓名',
PSEX varchar(10) comment '性别',
PAGE int(11) comment '年龄',
SAL decimal(7, 2) comment '工资',
PRIMARY KEY (PID)
);
# 创建存储过程
create procedure insert_person(in max_num int(10))
begindeclare i int default 0set autocommit = 0;repeatset i = i + 1;insert into person (PID,PNAME,PSEX,PAGE,SAL) values (i, concat('test', floor(rand()*10000000)),IF(RAND()>0.5,'男','女'), FLOOR((RAND()*100)+10),FLOOR((RAND()*19000)+1000));until i = max_numend repeat;commit;
end;-- 调用存储过程
call insert_person(3000000);-- 不使用索引,根据PNAME进行查询
select * from person where PNAME = 'test1209325'; #10.813秒-- 给PNAME建立普通索引
alter table person add index idx_pname(PNAME);
select * from person where PNAME = 'test1209325'; #5.032秒
-- 主键索引
select * from person where PID = 2800000; #0.021秒
explain 关键字
使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的。可以用来分析查询语句或是表的结构的性能瓶颈。其作用如下:
- 表的读取顺序
- 哪些索引可以使用
- 数据读取操作的操作类型
- 哪些索引被实际使用
- 表之间的引用
- 每张表有多少行被优化器查询
EXPLAIN 关键字使用起来比较简单: explain + SQL语句
准备测试数据:
-- 创建四张测试表
CREATE TABLE t1(id int(10) auto_increment,content varchar(100),primary key (id)
)CREATE TABLE t2(id int(10) auto_increment,content varchar(100),primary key (id)
)CREATE TABLE t3(id int(10) auto_increment,content varchar(100),primary key (id)
)CREATE TABLE t4(id int(10) auto_increment,content varchar(100),primary key (id)
)-- 每张表中添加一条数据
INSERT INTO t1(content) values (CONCAT('t1_',FLOOR(1+RAND()*1000)));
INSERT INTO t1(content) values (CONCAT('t2_',FLOOR(1+RAND()*1000)));
INSERT INTO t1(content) values (CONCAT('t3_',FLOOR(1+RAND()*1000)));
INSERT INTO t1(content) values (CONCAT('t4_',FLOOR(1+RAND()*1000)));
explain之id介绍
select 查询的序列号,表示查询中执行select子句或操作表的顺序。
# id相同时,执行顺序由上至下。
explain select * from t1,t2,t3 where t1.id = t2.id and t2.id=t3.id;` #得到表格1# id不同,如果是子查询,id的序号会递增,id值越大优先级越高,则先被执行。
explain select t1.id from t1 where t1.id in (select t2.id from t2 where t2.id in (select t3.id from t3 where t3.id = 1)
) # 得到表格2# id相同和不同都存在时,id相同的可以理解为一组,从上往下顺序执行,所有组中,id值越大,优先级越高越先执行。explain select t2.* from t2,(select * from t3) s3 where s3.id = t2.id; #得到表3
表格1:
id | select_type | table | type | possible_keys | key | ken_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | t1 | ALL | PRIMARY | null | null | null | 1 | |
1 | SIMPLE | t2 | eq_ref | PRIMARY | PRIMARY | 4 | db_test_t1.id | 1 | |
1 | SIMPLE | t3 | eq_ref | PRIMARY | PRIMARY | 4 | db_test_t1.id | 1 |
表格2:
id | select_type | table | type | possible_keys | key | ken_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | PRIMARY | t1 | index | null | PRIMARY | null | null | 1 | |
2 | DEPENDENT | t2 | unique_sub | PRIMARY | PRIMARY | 4 | func | 1 | Using index |
3 | SIMPLE | t3 | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
表格3:
id | select_type | table | type | possible_keys | key | ken_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | PRIMARY | <derived2> | system | null | null | null | null | 1 | |
1 | PRIMARY | t2 | const | PRIMARY | PRIMARY | 4 | const | 1 | |
2 | DERIVED | t3 | ALL | null | null | null | null | 1 |