zoukankan      html  css  js  c++  java
  • mysql创建索引,mysql索引优化,mysql索引创建删除

    mysql创建索引,mysql索引优化,mysql索引创建删除

    ================================

    ©Copyright 蕃薯耀 2020-11-23

    https://www.cnblogs.com/fanshuyao/

    一、mysql创建索引

    ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL]  INDEX | KEY  [索引名] (字段名1 [(长度)] [ASC | DESC]) [USING 索引方法]--
    CREATE  [UNIQUE | FULLTEXT | SPATIAL]  INDEX  索引名 ON  表名(字段名) [USING 索引方法]

    二、mysql查看索引

    show index from 表名;

    三、mysql删除索引

    DROP INDEX 索引名 ON 表名
    --
    ALTER TABLE 表名 DROP INDEX 索引名

    四、索引优化

    1、学生表

    CREATE TABLE student(
    id INT PRIMARY KEY  AUTO_INCREMENT,
    stu_no VARCHAR(30) NOT NULL,
    `name` VARCHAR(30),
    age INT ,
    mobile VARCHAR(11),
    `status` VARCHAR(1) DEFAULT '1' NOT NULL ,
    remark VARCHAR(100)
    );
    
    SELECT COUNT(*) FROM student;
    
    SELECT * FROM student;
    
    EXPLAIN SELECT * FROM student l WHERE l.`name`='学生11';
    
    EXPLAIN SELECT * FROM student l WHERE l.`stu_no`='1605782472487';
    
    EXPLAIN SELECT * FROM student l WHERE l.`stu_no`='1605782472487' AND l.`status`='1';
    
    EXPLAIN SELECT * FROM student l WHERE l.`name`='学生1' AND l.`stu_no`='1605782472487'; 
    
    EXPLAIN SELECT l.id,l.`stu_no`,l.`name` FROM student l WHERE l.`name`='学生1';
    
    EXPLAIN SELECT l.id,l.`stu_no`,l.`name` FROM student l WHERE l.`name`='学生1' ORDER BY l.`name`;
    
    -- 使用id排序,出现Using filesort
    EXPLAIN SELECT l.id,l.`stu_no`,l.`name` FROM student l WHERE l.`name`='学生1' ORDER BY l.`id`;
    
    EXPLAIN SELECT * FROM student l WHERE l.`name`='学生1' AND l.`mobile`='13400000001' AND l.`age`='21';
    
    -- 打乱顺序,正常使用索引
    EXPLAIN SELECT * FROM student l WHERE l.`age`='21'  AND l.`name`='学生1'   AND l.`mobile`='13400000001';
    
    -- 没用到索引
    -- type:ALL
    EXPLAIN SELECT l.id,l.`stu_no`,l.`name` FROM student l WHERE l.`name` LIKE '学生1%';
    
    -- 用到索引
    -- type:range,注意这里是range,不是index,即非全索引查找,是范围查找
    -- Using where; Using index
    -- 因为这里查询的字段只有name,name是建了索引的,右边%,索引还是生效,然后直接从索引取数据,而不是检索表,索引比表快
    EXPLAIN SELECT l.`name` FROM student l WHERE l.`name` LIKE '学生1%';
    
    -- 没用到索引
    -- type:ALL
    EXPLAIN SELECT l.id,l.`stu_no`,l.`name` FROM student l WHERE l.`name` LIKE '%学生1';
    
    -- 用到索引
    -- type:index
    -- Using where; Using index
    -- 因为这里查询的字段只有name,name是建了索引的,左边%,索引还是生效,然后直接从索引取数据,而不是检索表,索引比表快
    EXPLAIN SELECT l.`name` FROM student l WHERE l.`name` LIKE '%学生1';
    
    
    -- 没用到索引
    -- type:ALL
    EXPLAIN SELECT l.id,l.`stu_no`,l.`name` FROM student l WHERE l.`name` LIKE '%学生%';
    
    -- 用到索引
    -- type:index
    -- Using where; Using index
    -- 因为这里查询的字段只有name,name是建了索引的,左右两边%,索引还是生效,然后直接从索引取数据,而不是检索表,索引比表快
    EXPLAIN SELECT l.`name`,l.`mobile` FROM student l WHERE l.`name` LIKE '%学生%';
    
    -- 创建索引
    CREATE UNIQUE INDEX ind_stu_stuNO ON student(stu_no);
    CREATE INDEX ind_stu_name_mobile ON student(`name`,mobile);
    
    -- 删除索引
    DROP INDEX ind_stu_stuNO ON student;
    DROP INDEX ind_stu_name_mobile ON student;
    
    -- 查询表的索引
    SHOW INDEX FROM student;

    2、课程表

    CREATE TABLE course(
    id INT PRIMARY KEY  AUTO_INCREMENT,
    course_no VARCHAR(30) UNIQUE NOT NULL ,
    `name` VARCHAR(30),
    `status` VARCHAR(1) DEFAULT '1' NOT NULL ,
    create_time TIMESTAMP DEFAULT NOW() NOT NULL,-- 只有TIMESTAMP可以设置时间的默认值
    remark VARCHAR(100)
    );
    
    INSERT INTO course(course_no,`name`) VALUES('1001', '语文');
    INSERT INTO course(course_no,`name`) VALUES('1002', '数学');
    INSERT INTO course(course_no,`name`) VALUES('1003', '英语');
    INSERT INTO course(course_no,`name`) VALUES('1004', '物理');
    INSERT INTO course(course_no,`name`) VALUES('1005', '化学');
    INSERT INTO course(course_no,`name`) VALUES('1006', '生物');
    INSERT INTO course(course_no,`name`) VALUES('1007', '历史');
    INSERT INTO course(course_no,`name`) VALUES('1008', '地理');
    INSERT INTO course(course_no,`name`) VALUES('1009', '自然科学');
    INSERT INTO course(course_no,`name`) VALUES('1010', '体育');
    INSERT INTO course(course_no,`name`) VALUES('1011', '哲学');
    INSERT INTO course(course_no,`name`) VALUES('1012', '考古');
    INSERT INTO course(course_no,`name`) VALUES('1013', '高等数学');
    INSERT INTO course(course_no,`name`) VALUES('1014', '大学英语');
    INSERT INTO course(course_no,`name`) VALUES('1015', '艺术');
    
    
    SELECT * FROM course;
    
    -- 查询表的索引
    SHOW INDEX FROM course;

    3、学生课程关系表

    CREATE TABLE stu_course(
    id INT PRIMARY KEY  AUTO_INCREMENT,
    stu_id INT NOT NULL ,
    course_id INT NOT NULL ,
    create_time TIMESTAMP DEFAULT NOW() NOT NULL-- 只有TIMESTAMP可以设置时间的默认值
    );
    
    SELECT * FROM stu_course;
    
    SELECT COUNT(1) FROM stu_course;
    

    创建索引前后对比

    -- s  ref 1
    -- sc ALL 150646
    -- c  eq_ref 1
    EXPLAIN
    SELECT s.*,c.`name` FROM student s
    LEFT JOIN stu_course sc ON sc.`stu_id`=s.`id`
    LEFT JOIN course c ON c.`id`=sc.`course_id`
    WHERE s.`name`='学生1'
    ;
    
    -- 创建索引
    ALTER TABLE stu_course ADD INDEX stu_course_stuId(stu_id);
    
    
    -- 创建索引后
    -- s  ref 1
    -- sc ref 753
    -- c  eq_ref 1
    EXPLAIN
    SELECT s.*,c.`name` FROM student s
    LEFT JOIN stu_course sc ON sc.`stu_id`=s.`id`
    LEFT JOIN course c ON c.`id`=sc.`course_id`
    WHERE s.`name`='学生1'
    ;

    小表驱动大表:

    -- 加索引
    ALTER TABLE stu_course ADD INDEX stu_course_courseId(course_id);
    
    -- 小表驱动大表
    -- c  ALL 15
    -- sc ref 753
    EXPLAIN
    SELECT c.*,sc.`stu_id` FROM  course c 
    LEFT JOIN stu_course sc ON sc.`course_id`=c.`id`
    ;
    
    -- 大表驱动小表
    -- sc ALL    150646
    -- c  eq_ref 1
    EXPLAIN
    SELECT c.*,sc.`stu_id` FROM  course c 
    RIGHT JOIN stu_course sc ON sc.`course_id`=c.`id`
    ;
    
    -- 总结:尽量使用小表驱动大表

    in和EXISTS:

    -- in和EXISTS
    -- EXISTS查询语法
    SELECT select_list FROM a_table WHERE [NOT] EXISTS(subquery);
    
    -- in查询
    -- 1 sc ALL             150646
    -- 2 c  unique_subquery 1
    EXPLAIN
    SELECT * FROM stu_course sc WHERE sc.`course_id` IN (SELECT id FROM course c);
    
    -- sc ALL             150646
    -- c  unique_subquery 1
    EXPLAIN
    SELECT * FROM stu_course sc WHERE sc.`course_id` IN (SELECT id FROM course c WHERE c.`name` ='数学');
    
    -- EXISTS查询
    -- 1 sc ALL    150646    Using where
    -- 2 c  eq_ref 1          Using index
    EXPLAIN
    SELECT * FROM stu_course sc WHERE EXISTS (SELECT 1 FROM course c  WHERE c.`id`=sc.`course_id`);
    
    -- sc ALL    150646    Using where
    -- c  eq_ref 1        Using where
    EXPLAIN
    SELECT * FROM stu_course sc WHERE EXISTS (SELECT 1 FROM course c  WHERE c.`name` ='数学' AND  c.`id`=sc.`course_id`);
    
    -- in和EXISTS总结:
    -- EXISTS:可以理解为:将外查询(左边)表的每一行,代入内查询(右边)作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,
    -- 这一行行可作为外查询的结果行,否则不能作为结果。
    -- 1、通常情况下采用exists要比in效率高,因为IN不走索引。 -- 2、左边为小表时(in是大表),用in性能好。左边为大表时(EXISTS是小表),用EXISTS性能好。

    4、字典表

    -- 字典表
    -- drop table dict;
    CREATE TABLE dict(
    id INT PRIMARY KEY  AUTO_INCREMENT,
    `type` VARCHAR(30) NOT NULL, 
    `name` VARCHAR(30),
    `value` VARCHAR(50),
    create_time TIMESTAMP DEFAULT NOW() NOT NULL-- 只有TIMESTAMP可以设置时间的默认值
    );
    
    INSERT INTO dict(`type`,`name`,`value`) VALUES('status','有效', '1');
    INSERT INTO dict(`type`,`name`,`value`) VALUES('status','无效', '0');
    
    SELECT * FROM dict;

    ================================

    ©Copyright 蕃薯耀 2020-11-23

    https://www.cnblogs.com/fanshuyao/

  • 相关阅读:
    Web调用Linux客户端remmina运维
    前端和后端连载一起启动
    react redux 二次开发流程
    快上车,react 入门拾遗
    吐血整理!这篇带你彻底理解主存中存储单元地址的分配
    大学四年走来,这些网络工程师必备的模拟器我都给你整理好了
    主存、辅存、内存、外存、存储器是什么?还傻傻分不清楚?看完这一篇就够了
    一分钟理解系列—半导体存储芯片的知识点总结
    小白入门NAS—快速搭建私有云教程系列(一)
    五分钟理解主存储器的基本组成结构
  • 原文地址:https://www.cnblogs.com/fanshuyao/p/14023269.html
Copyright © 2011-2022 走看看