上篇博主给大家讲解了MySQL之、CRUD、函数及union查询,本篇给大家带来MySQL之视图&索引&执行计划,
官方解释:**MySQL中的视图是一种虚拟表,它是基于查询结果的可视化表示。视图可以简化复杂的查询操作,并提供了一种安全的方式来访问数据。索引是一种数据结构,用于加快数据库查询的速度。执行计划是MySQL优化器生成的一种描述查询执行方式的计划。**使大家更加的了解MySQL
create view 视图名
as
查询语句
方式一:create or replace view 视图名
as
查询语句
方式二:alter view 视图名
as
查询语句
drop view 视图名,视图名...
DESC 视图名;-----查看视图相关字段
SHOW CREATE VIEW 视图名;----查看视图相关语句
CREATE TABLE `t_mysql_score` (
`sid` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '学生编号,外键',
`cid` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '课程编号,外键',
`score` float NULL DEFAULT 0 COMMENT '成绩',
INDEX `sid`(`sid`) USING BTREE,
INDEX `cid`(`cid`) USING BTREE,
CONSTRAINT `t_mysql_score_ibfk_1` FOREIGN KEY (`sid`) REFERENCES `t_mysql_student` (`sid`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `t_mysql_score_ibfk_2` FOREIGN KEY (`cid`) REFERENCES `t_mysql_course` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '成绩信息表' ROW_FORMAT = Dynamic;
-- Records of t_mysql_score
-- ----------------------------
INSERT INTO `t_mysql_score` VALUES ('01', '01', 80);
INSERT INTO `t_mysql_score` VALUES ('01', '02', 90);
INSERT INTO `t_mysql_score` VALUES ('01', '03', 99);
INSERT INTO `t_mysql_score` VALUES ('02', '01', 70);
INSERT INTO `t_mysql_score` VALUES ('02', '02', 60);
INSERT INTO `t_mysql_score` VALUES ('02', '03', 80);
INSERT INTO `t_mysql_score` VALUES ('03', '01', 80);
INSERT INTO `t_mysql_score` VALUES ('03', '02', 80);
INSERT INTO `t_mysql_score` VALUES ('03', '03', 80);
INSERT INTO `t_mysql_score` VALUES ('04', '01', 50);
INSERT INTO `t_mysql_score` VALUES ('04', '02', 30);
INSERT INTO `t_mysql_score` VALUES ('04', '03', 20);
INSERT INTO `t_mysql_score` VALUES ('05', '01', 76);
INSERT INTO `t_mysql_score` VALUES ('05', '02', 87);
INSERT INTO `t_mysql_score` VALUES ('06', '01', 31);
INSERT INTO `t_mysql_score` VALUES ('06', '03', 34);
INSERT INTO `t_mysql_score` VALUES ('07', '02', 89);
INSERT INTO `t_mysql_score` VALUES ('07', '03', 98);
-- Table structure for t_mysql_student
-- ----------------------------
DROP TABLE IF EXISTS `t_mysql_student`;
CREATE TABLE `t_mysql_student` (
`sid` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '学生编号',
`sname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '学生名称',
`sage` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '学生年龄',
`ssex` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '学生性别',
PRIMARY KEY (`sid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '学生信息表' ROW_FORMAT = Dynamic;
-- Records of t_mysql_student
-- ----------------------------
INSERT INTO `t_mysql_student` VALUES ('01', '赵雷', '1990-01-01', '男');
INSERT INTO `t_mysql_student` VALUES ('02', '钱电', '1990-12-21', '男');
INSERT INTO `t_mysql_student` VALUES ('03', '孙风', '1990-12-20', '男');
INSERT INTO `t_mysql_student` VALUES ('04', '李云', '1990-12-06', '男');
INSERT INTO `t_mysql_student` VALUES ('05', '周梅', '1991-12-01', '女');
INSERT INTO `t_mysql_student` VALUES ('06', '吴兰', '1992-01-01', '女');
INSERT INTO `t_mysql_student` VALUES ('07', '郑竹', '1989-01-01', '女');
INSERT INTO `t_mysql_student` VALUES ('09', '张三', '2017-12-20', '女');
INSERT INTO `t_mysql_student` VALUES ('10', '李四', '2017-12-25', '女');
INSERT INTO `t_mysql_student` VALUES ('11', '李四', '2012-06-06', '女');
INSERT INTO `t_mysql_student` VALUES ('12', '赵六', '2013-06-13', '女');
INSERT INTO `t_mysql_student` VALUES ('13', '孙七', '2014-06-01', '女');
-- Table structure for t_mysql_teacher
-- ----------------------------
DROP TABLE IF EXISTS `t_mysql_teacher`;
CREATE TABLE `t_mysql_teacher` (
`tid` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '教师编号',
`tname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '教师名称',
PRIMARY KEY (`tid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '教师信息表' ROW_FORMAT = Dynamic;
-- Records of t_mysql_teacher
-- ----------------------------
INSERT INTO `t_mysql_teacher` VALUES ('01', '张三');
INSERT INTO `t_mysql_teacher` VALUES ('02', '李四');
INSERT INTO `t_mysql_teacher` VALUES ('03', '王五');
SET FOREIGN_KEY_CHECKS = 1;
select * from t_mysql_student s,t_mysql_score
sc where s.sid=sc.sid;
create view v_student_score
as
select * from t_mysql_student s,t_mysql_score
sc where s.sid=sc.sid;
create view v_student_score
as
select s.*,sc.cid,sc.score from t_mysql_student s,t_mysql_score
sc where s.sid=sc.sid;
完成之后,就不需要像前面那样去连表查询了
直接查视图就行了,就像操作一张表一样去操作数据
select * from v_student_score;
desc v_student_score
show create view v_student_score
drop view v_student_score
索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录。
使用索引可以很大程度上提高数据库的查询速度,还有效提高了数据库系统的性能
is null
可以走索引,is not null
无法使用索引(取决于某一列的具体情况)CREATE TABLE 't_log'(
'id' varchar(32) NOT NULL COMMENT '唯一标识',
'ip' varchar(15) NOT NULL COMMENT 'IP地址',
'userid' varchar(32) NOT NULL COMMENT '用户ID',
'moduleid' varchar(32) NOT NULL COMMENT '模块ID',
'content' varchar(500) NOT NULL COMMENT '日志内容',
'createdate' timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期',
'url' varchar(100) DEFAULT NULL COMMENT '请求URL地址',
PRIMARY KEY('id')
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
select * from t_log;
select * from t_log where moduleid='10040199';
Create index idx_moduleid on t_log(moduleid);
select * from t_log where moduleid='10040199';
EXPLAIN select * from t_log where moduleid='10040199'
DUPlicate entry '/quartz/queryJobLst'for key 'idx_url'有重复列段
create UNIQUE index idx_url on t_log(url);
drop index idx_urlon t_log;
select * from t_log where id='123456';
EXPLAIN select * from t_log where id='123456';
create index idx_userid_moduleid_url on t_log(userid,moduleid,url);
–走组合索引
EXPLAIN select * from t_log where userid="and moduleid = " and url= ";
EXPLAIN select * from t_log where userid = " and moduleid = ";
EXPLAIN select * from t_log where userid = ";
EXPLAIN select * from t_log where userid=" and url =";
–不走组合索引
EXPLAIN select * from t_log where moduleid=";
EXPLAIN select * from t_log where url=";
EXPLAIN select * from t_log where moduleid=" and url=";
–创建索引
CREATE [UNIQUE|FULLTEXT] INDEX 索引名 ON 表名(字段名[(长度)][ASC|DESC])
1)表的读取顺序
2)数据读取操作的操作类型
3)哪些索引可以使用
4)哪些索引被实际使用
5)每张表有多少行被优化器查
1)id相同的情况下执行顺序是由上到下
2)id越大优先级越高,如果是子查询,ID序列号会递增,id值越大,优先级越高,越先执行。
3)id相同又有不相同的,序列号大的会先执行,然后相同的从上到下执行。
1)simple:简单的select查询,不包含之查询或者union
2)primary:查询中包含任何复杂的子部分,最外层查询则被标记
3)subquery:在select或者where列表中包含了子查询
4)derived:在from列表中包含子查询被标记为derived Mysql会递归执行这些子查询,把结果放到临时表里
5)union:诺在第二个select中出现union之后,则被标记为union,诺union包含在from子句的子查询中,外层select将被标记为derived
6)union result:从union表获取结果的SELECT
system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>all
`注:`一般来说,得保证查询至少达到range级别,最好能达到ref
SELECT
s.*,
( CASE WHEN t1.cid = '01' THEN t1.score END ) 语文,
( CASE WHEN t2.cid = '02' THEN t2.score END ) 数学
FROM
t_mysql_student s,
( SELECT * FROM t_mysql_score WHERE cid = '01' ) t1,
( SELECT * FROM t_mysql_score WHERE cid = '02' ) t2
WHERE
s.sid = t1.sid
AND t1.sid = t2.sid
AND t1.score > t2.score;
02)查询同时存在" 01 “课程和” 02 "课程的情况
①分析:涉及表 t_mysql_student,t_mysql_score 这个学生既要有01的分数也要有02的分数,那么这张表要当两次来用
②连接方式:内连接
③行转列:流程函数
SELECT
s.*,
( CASE WHEN t1.cid = '01' THEN t1.score END ) 语文,
( CASE WHEN t2.cid = '02' THEN t2.score END ) 数学
FROM
t_mysql_student s,
( SELECT * FROM t_mysql_score WHERE cid = '01' ) t1,
( SELECT * FROM t_mysql_score WHERE cid = '02' ) t2
WHERE
s.sid = t1.sid
AND t1.sid = t2.sid;
03)查询存在" 01 “课程但可能不存在” 02 "课程的情况(不存在时显示为 null )
①连接方式:外连接
②行转列:流程函数
SELECT
s.*,
( CASE WHEN t1.cid = '01' THEN t1.score END ) 语文,
( CASE WHEN t2.cid = '02' THEN t2.score END ) 数学
FROM
t_mysql_student s
INNER JOIN ( SELECT * FROM t_mysql_score WHERE cid = '01' ) t1 ON s.sid = t1.sid
LEFT JOIN ( SELECT * FROM t_mysql_score WHERE cid = '02' ) t2 ON t1.sid = t2.sid;
04)查询不存在" 01 “课程但存在” 02 "课程的情况
①分析:先查出存在01的学生有哪些,然后再排除掉。子查询
SELECT
s.*,
( CASE WHEN sc.cid = '01' THEN sc.score END ) 语文,
( CASE WHEN sc.cid = '02' THEN sc.score END ) 数学
FROM
t_mysql_student s,
t_mysql_score sc
WHERE
s.sid = sc.sid
AND s.sid NOT IN ( SELECT sid FROM t_mysql_score WHERE cid = '01' )
AND sc.cid = '02'
05)查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
①分析:聚合函数意味着分组,外连接
SELECT
s.sid,
s.sname,
round( avg( sc.score ), 2 ) 平均成绩
FROM
t_mysql_student s
LEFT JOIN t_mysql_score sc ON s.sid = sc.sid
GROUP BY
s.sid,
s.sname
HAVING
平均成绩 >= 60
06)查询在t_mysql_score表存在成绩的学生信息
①分析:表两张:学生表,成绩表。内连接
SELECT
s.sid ID,
s.sname 姓名
FROM
t_mysql_student s
INNER JOIN t_mysql_score sc ON s.sid = sc.sid
GROUP BY
s.sid,
s.sname
07)查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
①分析:聚合函数
②外连接
SELECT
s.sid,
s.sname,
count( sc.score ) 选课总数,
sum( sc.score ) 总成绩
FROM
t_mysql_student s
LEFT JOIN t_mysql_score sc ON s.sid = sc.sid
GROUP BY
s.sid,
s.sname
select count(*) 数量 from t_mysql_teacher where tname like '李%'