1 从浏览器输入一个地址,到看到页面信息,经历的过程
2 左连接,右连接,内连接,全连接:MySQL不能直接支持
3 union和union all的区别?
4 一句sql查询慢,如何排查优化
1 从浏览器输入一个地址,到看到页面信息,经历的过程
1 在浏览器中输入的是:【协议,地址,不带端口,默认是80端口】域名-----协议解析
----如果是http/s---》要做域名解析(DNS解析)-----》把域名解析成ip地址+端口的形式---dns解析
---》(浏览器缓存(一旦之前访问过这个地址,浏览器会自动加缓存,再访问--》直接从缓存中获取
--》F5强制刷新或者浏览器有无痕)--》dns解析:先解析本地host文件,上一级递归解析服务,
13台根dns)--》如果解析不到---》页面就会报错
2 解析完后,向解析出的ip地址和端口,准备建立TCP连接(http/s,底层基于tcp),
可靠链接,tcp处于传输层,进行3次握手,链接建立
3 向解析出的地址发送http的get请求---》http协议又有很多东西,暂时先不说:请求首行:请求路径,
请求协议版本,请求方式 ,请求头,请求体
4 如果后端服务是使用nginx转发,做反向代理服务器,nginx把http请求转发给web框架(django,flask)
--》django请求生命周期---》分离项目和混合项目
5 后端服务器以http响应的形式返回给客户端浏览器
6 客户端浏览器先判断响应状态码,如果状态码是成功的,把http响应体的内容展示在浏览器上,
但是http响应还有:响应首行,响应头,响应体
7 四次挥手断开tcp连接---》这个链接不一定会断开---》http协议版本
-参考博客文章:
https://blog.csdn.net/m0_52165864/article/details/126313277
-注意:
响应状态码放在响应首行
2 左连接,右连接,内连接,全连接:MySQL不能直接支持
-数据通常不在同一张表中,这就涉及到连表操作,而表之间连接方式有很多,能够连表,
大前提是多表之间有关联关系[外键关系],呈现出三种关系:一对一,一对多,多对多
-内连接:把两张表中共有的数据,连接到一起
select * from book inner join publish on book.publish_id=publish.id
-左连接:以左表为基准,把左表所有数据都展示,有可能右表没有,用空补齐
select * from book left join publish on book.publish_id=publish.id
-右连接:以右表为基准,把右表所有数据都展示,有可能左表没有,用空补齐
select * from book right join publish on book.publish_id=publish.id
-全连接:以左右两表数据作为基准,左右两表数据都展示,有可能左或表没有,用空补齐
select * from book left join publish on book.publish_id=publish.id
union
select * from book right join publish on book.publish_id=publish.id
-myslq不支持全连接---》左连接结果 union 右连接的结果
-笛卡尔积
select * from book,publish where book.publish_id=publish.id;
第一个表
id name age publish_id
1 xx 11 1
2 yy 12 1
第二个表
id name age
1 xx 11
2 yy 12
1 xx 11 1 1 xx 11
1 xx 11 1 2 yy 12
2 yy 12 1 1 xx 11
2 yy 12 1 1 yy 12
# 笛卡尔积后通过外键的限定条件(where) ,得到的结果跟内连接一致
-左右键连接
2 左连接,右连接,内连接,全连接:MySQL不能直接支持
select * from book left join publish on book.publish_id=publish.id;
book.publish_id=99
publish.id没有99
-连表写sql
select * from user, userdetail where user.id=userdetail.user_id;
select * frrom user inner join userdetail on user.id=userdetail.user_id;
1. **左连接(Left Join):**
SELECT stu.sid '学号', stu.sname '姓名', stu.gender '性别',
stu.class_id '班级', score.num '分数', score.course_id '课表编号'
FROM student as stu
LEFT JOIN score ON stu.sid = score.student_id;
2. **右连接(Right Join):**
SELECT stu.sid '学号', stu.sname '姓名', stu.gender '性别',
stu.class_id '班级', score.num '分数', score.course_id '课表编号'
FROM student as stu
RIGHT JOIN score ON stu.sid = score.student_id;
3. **内连接(Inner Join):**
SELECT student.sid '学号', student.sname '姓名', student.gender '性别',
student.class_id '班级', score.num '分数', score.course_id '课表编号'
FROM student
INNER JOIN score ON student.sid = score.student_id;
4. **全连接(Full Join):**
MySQL 不直接支持 `FULL JOIN`,但可以通过 `LEFT JOIN` 和 `UNION` 或者 `RIGHT JOIN`
和 `UNION` 的组合来实现全连接:
-- 使用 LEFT JOIN 和 UNION 实现全连接
SELECT * FROM table1
LEFT JOIN table2 ON table1.id = table2.id
UNION
SELECT * FROM table1
RIGHT JOIN table2 ON table1.id = table2.id;
或者:
-- 使用 RIGHT JOIN 和 UNION 实现全连接
SELECT * FROM table1
RIGHT JOIN table2 ON table1.id = table2.id
UNION
SELECT * FROM table1
LEFT JOIN table2 ON table1.id = table2.id;
这些语法是标准 ANSI SQL 语法,因此在大多数支持 SQL 的关系型数据库中都可以使用。
MySQL 支持这些语法,可以通过它们来执行不同类型的连接操作。
建表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for class
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
`cid` int(11) NOT NULL AUTO_INCREMENT,
`caption` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of class
-- ----------------------------
INSERT INTO `class` VALUES (1, '三年二班');
INSERT INTO `class` VALUES (2, '三年三班');
INSERT INTO `class` VALUES (3, '一年二班');
INSERT INTO `class` VALUES (4, '二年九班');
-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`cid` int(11) NOT NULL AUTO_INCREMENT,
`cname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`teacher_id` int(11) NOT NULL,
PRIMARY KEY (`cid`) USING BTREE,
INDEX `fk_course_teacher`(`teacher_id` ASC) USING BTREE,
CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`tid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES (1, '生物', 1);
INSERT INTO `course` VALUES (2, '物理', 2);
INSERT INTO `course` VALUES (3, '体育', 3);
INSERT INTO `course` VALUES (4, '美术', 2);
-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) NOT NULL,
`course_id` int(11) NOT NULL,
`num` int(11) NOT NULL,
PRIMARY KEY (`sid`) USING BTREE,
INDEX `fk_score_student`(`student_id` ASC) USING BTREE,
INDEX `fk_score_course`(`course_id` ASC) USING BTREE,
CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 53 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES (1, 1, 1, 10);
INSERT INTO `score` VALUES (2, 1, 2, 9);
INSERT INTO `score` VALUES (5, 1, 4, 66);
INSERT INTO `score` VALUES (6, 2, 1, 8);
INSERT INTO `score` VALUES (8, 2, 3, 68);
INSERT INTO `score` VALUES (9, 2, 4, 99);
INSERT INTO `score` VALUES (10, 3, 1, 77);
INSERT INTO `score` VALUES (11, 3, 2, 66);
INSERT INTO `score` VALUES (12, 3, 3, 87);
INSERT INTO `score` VALUES (13, 3, 4, 99);
INSERT INTO `score` VALUES (14, 4, 1, 79);
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`gender` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`class_id` int(11) NOT NULL,
`sname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`sid`) USING BTREE,
INDEX `fk_class`(`class_id` ASC) USING BTREE,
CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '男', 1, '王八');
INSERT INTO `student` VALUES (2, '女', 1, '钢蛋');
INSERT INTO `student` VALUES (3, '男', 1, '张三');
INSERT INTO `student` VALUES (4, '男', 1, '张一');
INSERT INTO `student` VALUES (5, '女', 1, '张二');
INSERT INTO `student` VALUES (6, '男', 1, '张四');
INSERT INTO `student` VALUES (7, '女', 2, '铁锤');
INSERT INTO `student` VALUES (8, '男', 2, '李三');
INSERT INTO `student` VALUES (9, '男', 2, '李一');
INSERT INTO `student` VALUES (10, '女', 2, '李二');
INSERT INTO `student` VALUES (11, '男', 2, '李四');
INSERT INTO `student` VALUES (12, '女', 3, '如花');
INSERT INTO `student` VALUES (13, '男', 3, '刘三');
INSERT INTO `student` VALUES (14, '男', 3, '刘一');
INSERT INTO `student` VALUES (15, '女', 3, '刘二');
INSERT INTO `student` VALUES (16, '男', 3, '刘四');
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`tid` int(11) NOT NULL AUTO_INCREMENT,
`tname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`tid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES (1, '张三老师');
INSERT INTO `teacher` VALUES (2, '李四老师');
INSERT INTO `teacher` VALUES (3, '王五老师');
INSERT INTO `teacher` VALUES (4, '赵六老师');
INSERT INTO `teacher` VALUES (5, '钱七老师');
-- ----------------------------
-- View structure for teacher2course
-- ----------------------------
DROP VIEW IF EXISTS `teacher2course`;
CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `teacher2course` AS
select
`teacher`.`tid` AS `tid`,`teacher`.`tname` AS `tname`,
`course`.`cid` AS `cid`,`course`.`cname` AS `cname`,
`course`.`teacher_id` AS `teacher_id`
from (`teacher` join `course` on((`teacher`.`tid` = `course`.`teacher_id`)));
-- ----------------------------
-- Procedure structure for p2
-- ----------------------------
DROP PROCEDURE IF EXISTS `p2`;
delimiter ;;
CREATE PROCEDURE `p2`(in m int, # in表示这个参数必须只能是传入不能被返回出去
in n int,
out res int)
begin
SELECT tname FROM teacher WHERE tid > m and tid < n;
set res = 0; # 用来标志存储过程是否执行
end
;;
delimiter ;
SET FOREIGN_KEY_CHECKS = 1;
3 union和union all的区别?
-作用:select 出来结果,union,union all都是对结果进行合并,并对结果进行排序,
求并集,字段类型和列都要一致才能用
union 会去除重复的数据,去重和排序操作
union all 不会去除重复的数据,不会去重和排序
select id,name from user where id <3;
1 lqz
2 lqz1
3 lqz2
select id,name from user where id >2;
3 lqz3
4 lqz4
5 lqz5
select name,id form user;
id name
1 lqz
2 zs
select name,id form book;
id name
1 lqz
2 西游记
3 金瓶梅
select name,id form user union all select name,id form book;
id name
1 lqz
2 zs
1 lqz
2 西游记
3 金瓶梅
select name,id form user union select name,id form book;
id name
1 lqz
2 zs
2 西游记
3 金瓶梅
`UNION` 和 `UNION ALL` 是 SQL 中用于合并查询结果的两个操作符,它们之间的主要区别在于是否去重。
1. **UNION:**
- `UNION` 用于合并两个或多个 SELECT 语句的结果集,并去除重复的行。
- `UNION` 对结果集执行去重操作,确保最终的结果中不包含重复的行。
- 由于要进行去重的操作,`UNION` 的性能开销可能较大。
-- 左连接
SELECT student.sid, student.gender, student.class_id, student.sname, score.num
FROM student
LEFT JOIN score ON student.sid = score.student_id
UNION
-- 查询 score 表中没有匹配的记录
SELECT student.sid, student.gender, student.class_id, student.sname, NULL AS num
FROM student
WHERE student.sid NOT IN (SELECT student_id FROM score);
2. **UNION ALL:**
- `UNION ALL` 也用于合并两个或多个 SELECT 语句的结果集,但不去除重复的行。
- `UNION ALL` 返回包含所有行的结果,包括重复的行。
- 由于不需要去重,`UNION ALL` 的性能通常比 `UNION` 更高效。
-- 右连接
SELECT student.sid, student.gender, student.class_id, student.sname, score.num
FROM student
RIGHT JOIN score ON student.sid = score.student_id
UNION ALL
-- 查询 student 表中没有匹配的记录
SELECT NULL AS sid, NULL AS gender, NULL AS class_id, NULL AS sname, score.num
FROM score
WHERE score.student_id NOT IN (SELECT sid FROM student);
**总结区别:**
- `UNION` 执行结果集的去重操作,确保最终结果中不包含重复的行。
- `UNION ALL` 返回包含所有行的结果,包括重复的行。
- 由于去重操作,`UNION` 的性能通常较慢,而 `UNION ALL` 性能较快。
- 如果确定结果中没有重复的行,可以优先选择使用 `UNION ALL`,以提高性能。
**注意:**
- `UNION` 和 `UNION ALL` 要求合并的查询具有相同的列数和相似的数据类型。
4 一句sql查询慢,如何排查优化
1 orm ,把orm转成原生sql,再做分析
2 开启慢查询---》定位慢sql
3 接口响应速度慢---》定位到是sql问题
-1 索引优化:分析sql有没有走索引----》EXPLAIN SELECT * FROM orders WHERE name = 123;
在表中添加合适的索引可以显著提升查询效率。可以通过 EXPLAIN 命令来查看查询计划,
判断是否使用了索引,如果没有使用索引,就需要考虑添加索引
-2 避免全表扫描:避免在大表上进行全表扫描,可以通过限制查询条件(where)
或者使用分页(limit)查询来解决
-使用分页,避免全表搜索,扫描
-3 优化查询语句:
EXPLAIN SELECT * FROM orders WHERE name like 123%;
-优化sql,不要写 前面的模糊查询
-尽量使用主键查询,尽量不模糊匹配
-尽量不要使用select *
-4 数据库表结构优化
-大表拆成小表
-垂直
-水平
-5 做数据库读写分离
-6 分库分表
慢查询就是运行时间比较长的SQL语句
1、会导致创建表,修改表,删除表,执行数据备份等操作都需要等待
2、会占用mysql的大量内存,严重的会导致系统瘫痪
3、因为默认的隔离级别是可重复读,会造成数据库幻读
4、严重影响用户体验,sql执行时间越长,页面加载数据耗时也长
定位慢sql
暂时开启慢sql监控,配置文件永久开启慢sql监控 配置慢sql阀值
--开启慢 SQL 监控
查看是否开启慢sql监控:slow_query_log
show variables like 'slow_query_log%';
开启慢查询监控:set global slow_query_log = 1;
关闭慢sql监控:set global slow_query_log = 0;
--配置慢 SQL 阀值
默认的慢sql阀值,默认阀值是10秒,查询慢sql的阀值
show variables like "long_query_time";
修改慢sql的阀值
set global long_query_time = 0.2;
退出客户端,重新连接服务器,就生效
但是服务器重启之后,当前配置就会失效
--永久开启慢sql监控
修改全局配置文件my.cnf,永久生效
--mysqldumpslow
MySQL自带了一个慢查询分析工具mysqldumpslow来分析
sql语句常见优化
1 sql语句优化,尽量精简,去除非必要语句,查询优化,避免使用select *的操作,使用in替换or,
有索引的时候这两个执行速度差不多,但是没有索引的时候,in的执行速度比or大
2 数据库结构优化:有些字段使用率比较高,有些低,数据量大的时候,将字段多的表分成多个表
3 索引优化,能添加索引的都添加索引 (EXPLAIN 可以查看是否使用了索引
EXPLAIN SELECT * FROM orders WHERE name = 123;)