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/