6-从浏览器输入一个地址,到看到页面信息,经历的过程。左连接,右连接,内连接,全连接:MySQL不能直接支持。union和union all的区别?一句sql查询慢,如何排查优化

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 出来结果,unionunion 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的执行速度比or2 数据库结构优化:有些字段使用率比较高,有些低,数据量大的时候,将字段多的表分成多个表  
3 索引优化,能添加索引的都添加索引 (EXPLAIN 可以查看是否使用了索引  
	EXPLAIN SELECT * FROM orders WHERE name = 123;

你可能感兴趣的:(面试题,mysql,union,union,all,left,join,right,join,browser)