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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM