测试工程师社招-mysql面试题
一、关于查询
1、distinct删除重复行
Select distinct 列名 from 表名;
Count(distinct device_id) 聚合函数
面试题mysql有哪几种方式去重:1、distinct,对所有列进行去重2、group by,对指定列进行分类,去重2、union,将两个或者多个语句合并进行去重4、inner join将两个或者两个表连接起来,获取某一列去重的结果5、not in根据另一个查询结果过滤当前查询结果
2、别名,修改显示的标题
Select name ‘s_name’ from stu;
Select name as s_name from stu;
3、条件查询,多个条件可以用and或or连接,union all连接两个查询不去重
Select name from stu where name = ‘zmx’ and sex = ‘female’;
Select device_id,gender from user_profile where university = ‘aaa’ union all select device_id,gender from user_profile where gender = ‘male’;(同一个表两个查询结果并集)
4、比较搜索条件
<>= != !> !<
Select * from person where age<23;
5、返回搜索条件
在范围之内:select * from stu where age between 10 and 20;(闭区间)
不在范围之内:select * from stu where age not between 10 and 20;
多个区间:
Case
When age>=25 then ‘25+’
When age>=20 then ‘20-24’
When age<20 then ‘20-’
Else ‘其他’
End as age_cut
案例:
Select device_id,gender
Case
When age>=25 then ‘25+’
When age<25 or age is null then ‘25-’
End as age_cut
From user_profile;
6、in,只要匹配到括号里面任何一个值就有查询结果
Select * from stu where id in(1,2,3,4……)
Select * from stu where id not in (1,2,3,4……)
7、模糊查询like
%表示0个或者多个字符,_表示一个字符
Select * from stu where name like ‘z%’;
Select* from stu where name like ‘_mx’;
字符串截取:substring_index(profile,’,’,3)
案例:select substring_index(substring_index(profile,’,’3),’,’,-1) as age_cut,count(device_id) as number from user_submit group by age;(关键词:每个年龄group by,先截取前半部分在截取后半部分)
8、涉及空值的查询
Select * from person where age is null;
Select * from person where age is not null;
9、聚合函数
Count(*):统计表中元祖的个数,不忽略null
Count(列名):统计表中某个列有多少条记录,忽略null
Sum avg max min 忽略null值
10、limit [start,] nums:默认从0开始计数,总共要查询几行
Select * from person limit 4,1;(只查询第五行)
Select * from person limit 2,3;(从第三行开始,查询三行)
11、group by having分组查询,having可以包含聚合函数,where不可以
Select sex,min(age) from peson group by sex;(根据性别查看最小年龄)
面试题:Select name,min(score) from stu group by name having min(score)>80;(找出表中分数大于80的名字名字有重复的,name分组,每个名字下分数的最小值大于80)
Select * from person group by name having age<23;(年龄小于22的)
Select * from sc group by id having sum(score)<600;(总成绩小于600)
12、排序,默认升序
Select * from person order by id desc|asc;
Select * from person order by gpa desc,age desc;(分别排序并组合)
面试题-sql语句执行顺序:from表、join连接表、where、group by(聚合函数,然后having)、 然后执行select语句进行筛选,最后去除重复的数据distinct、数据进行排序order by、limit结果限定
二、mysql中的函数
1、字符串函数
Length:字符串字节长度,中文占两个字节,比如:select id,length(name) as ‘姓名长度’ from student;
Char_length:字符串字节长度,中文占一个字节,比如:select id,char_length(name) from student;
Mid:截取,从某一个位置获取某个长度的字符,比如:select id,mid(name,2,1) as ‘m_name’ from stu;(2为开始位置,最小值是1,1位要截取的长度)
Round:实现四舍五入,比如:select round(avg(age),3) from stu;(age保留三位小数)
Least:可以求最小的数字 least(1,2,3,4,5,6)
Greatest:可以求最大的数字 greatest(2,1,4,5)
2、日期和时间函数
Now():当前日期时间
Current_date():当前日期
Current_time():当前时间
To_days(now()):日期转换成总天数
Dayofyear(now()):该年已过天数
Week():当前日是第几周
DATEDIFF():查看某一段时间的天数,比如:select datediff(end_date,start_date) as days from orders where start_date>=”2023-11-28” and end_date<=”2023-12-19”;
3、控制函数
if有三个函数,第一个参数为空输出第三个参数,否则输出第二个参数
Select if(null,’你好’,’你不好’)
ifnull有两个参数,第一个为空输出第二个,否则输出第一个
Select ifnull(null,’你好’)
三、表连接,多表查询
内连接:只有匹配到的情况下才会返回结果值
第一种:select sc.grade,stu.sname from sc,stu where sc.sno=stu.sno;
第二种:select sc.sno,sc.grade,stu.sname from sc inner join stu on sc.sno=stu.sno and sc.grade>80;(inner可有可无,join一定要写)
若两个表没有相同的地方作为连接条件,找一个中间表
方法一:select stu.sname,sc.sdept from stu,course,sc where stu.sno=sc.sno,sc.cno=course.cno and course.cname = ‘VB’;
方法二:select stu.sname,sc.sdept from stu inner join sc on stu.sno=sc.sno inner join course on sc.cno=course.cno where course.sname=’VB’;(先两两结合,然后在连接两一个表)
外连接:外部连接会返回from子句提到的至少一个表或者视图中的所有行,不匹配的显示null。
左:对左表不加限制,左表中的数据可以为空
右:对右表不加限制,右表中的数据可以为空
四、子查询
单值子查询,这样的子查询只返回一个值
Select * from sc,stu where sc.sno = stu.sno and sc.sno=(select sno from stu where sname = ‘zmx’);
子查询:在其他查询结果的基础之上提供一种有效的方式来表示where子句的条件。可以嵌套在select insert update delete语句之中。外面查询什么里面就查询什么。
Select sno,grade from sc where cno = ‘c02’ and grade>(select avg(grade) from sc where cno = ‘c02’);
嵌套子查询:一个子查询中还可以包含另一个子查询 最多255个
比如:select cno from sc where sno in(select sno from stu where sdept = ‘计算机系’);
(从sc表里面来查询cno 但是要查询计算机系的学生号sc里面没有计算机系,所以根据stu里面的学号来查询)
五、其他面试题参考
https://www.cnblogs.com/souyunku/p/15633392.html
1、Mysql慢查询
Msql慢查询是指执行时间超过预设阈值的查询语句,可以通过分析慢查询日志,找出执行时间较长的查询语句,优化数据库性能。1、适当使用索引2、优化查询语句,减少不必要的连接和子查询3、避免全表扫描4、避免使用子查询6、避免使用聚合函数7、定期分析慢查询日志,找出执行时间较长的查询语句
Show variables like ‘show_query_log’;查看慢查询日志的配置
Set global show_query_log =’on’;开启慢查询日志
Set global long_query_time = 1;设置慢查询阈值,秒
Show variables like ‘show_query_log_file’;查看慢查询日志文件路径
Select * from mysql.slow_log;分析慢查询日志
2、redis数据库
本质上是一个key-value内存数据库(受物理内存的限制,主要集中在较小数据量和高性能运算上)
支持哪几种类型:string、list、set、sorted set、hashes
3、主键索引和唯一索引区别
1、主键是约束,唯一索引是索引,本质区别
2、主键创建后包含一个唯一索引,唯一索引不一定是主键
3、唯一索引允许空值,主键不允许空值
4、一个表只能创建一个主键,多个唯一索引
4、优化sql查询
1、尽量避免全表扫描,指定具体某个列
2、避免在where中使用or,or会导致扫描(union all 分两个写)
3、避免使用null is null in not in (可能放弃索引)
4、索引
https://www.sohu.com/a/601934836_121124376
5、cpu飙升
top命令观察、是不是有消耗资源的sql在运行、找出消耗高的sql;
调整:kill掉这些线程、调整(改sql、加索引、改内存参数)
6、索引的数据结构:B+树索引(索引存储在硬盘上)
平衡二叉树升级为B树(树的高度问题),然后升级为B+树(适合范围查找)
平衡二叉树左子树和右子树高度不会超过1,但是随着树越高,查找速度也会变慢;
B树最大特点一个结点存两个值,树的高度变矮了;
B+树,一个结点存两个值,叶子结点链表排序,解决回旋链表的问题(单向链表)(非叶子结点-只存储key,叶子结点存储key和地址)
7、数据库连接池
一组可复用的数据库连接,目的是减少数据库连接的建立和关闭的次数,从而提高效率。(原理:在数据库连接池中维护一组可重用的数据库连接,当一个客户端程序需要访问数据库时,它可以从连接池中获取一个可用的连接,使用完后,连接不会立即关闭而是回到连接池中)