- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563374 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174235
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
拼多多面试问了数据库基础知识,今天分享出来
8 ~& `; v, j& I! V7 p. P( M
5 ~! S8 ?; a9 F; `$ K! [1 b+ b# z: _前言
7 R1 [4 ^9 ^ z9 p. c! R' a, ?1 [9 V5 j2 x b& O9 c' w* S9 X
我是个标题党,所有文章的名字只是我的噱头,我们应该有一颗谦逊的心,所以希望大家怀着空杯心态好好学,一起进步。
* ?6 X# f X# |! b# T+ V$ C& w+ _9 X! k$ C! {
数据库我想大家应该一点都不陌生吧,我想不管你写啥的,数据库就算没用过也听过了,是我们项目体系里面不可或缺的一环。( X' x4 ?! P( y
( n* y6 U5 t# M1 B3 W3 u5 }4 s问了一圈,身边朋友公司要么用自研,要么就清一色的MySQL,所以想看Oracle的朋友可能要失望了,但是不影响你了解数据库的通用知识。- N% c: C3 L6 J: P+ w* Z6 i7 I
" ~! E2 W- w1 E8 l8 X# J( V+ @) c
正文0 E8 m8 i7 _6 j
$ \( w+ g, s( x- V& Y2 P
你知道MySQL的基本架构么?你能在纸上给我大致画出这个示意图么?
! t' ]. g4 S' V1 D8 C) v- O2 A
+ B; a: ?, j5 R好的那我们按照顺序了解下,连接器是啥?$ A5 G2 S( m2 y& L+ j! H$ E
我们要进行查询,第一步就是先去链接数据库,那这个时候就是连接器跟我们对接。
/ z( f$ N! S' M
0 b. {. s. t- i8 r, I: b& b4 G' f他负责跟客户端建立链接、获取权限、维持和管理连接。% ` R. w8 L2 ^
5 u) Q# s" E" h; _( X6 l* V- o0 i
链接的时候会经过TCP握手,然后身份验证,然后我们输入用户名密码就好了。; A1 ]; L8 A2 b+ b9 x
! M% G% x; a' l! e
验证ok后,我们就连上了这个MySQL服务了,但是这个时候我们处于空闲状态。* z* F7 p, W5 |' O3 a. b" |+ r
& M9 u- M c" F4 Y3 r9 U% t
怎么查看空闲连接列表?
0 k+ E7 C5 @9 [show processlist,下图就是我在自己的数据库表执行命令的结果,其中的Command列显示为Sleep的这一行,就表示现在系统里面有一个空闲连接。2 C' j' ^2 U& `3 s) z" X9 H
4 v9 E' Z N+ d4 z' W$ r
这里需要注意的是,我们数据库的客户端太久没响应,连接器就会自动断开了,这个时间参数是wait_timeout控制住的,默认时长为8小时。9 p+ J. b$ O+ P6 R( Z
! B$ V( P$ W$ |4 t- ^
断开后重连的时候会报错,如果你想再继续操作,你就需要重连了。
* t1 R4 O3 t) Q; t0 D0 z, N5 P
. N" E- J8 A5 m, \6 d这个有个我看过的书本的案例:; q( L, `# ]: Q# f) Y2 |2 F: P8 U
6 a% J# y# S: s# Z6 S ^
一个在政府里的朋友说,他们的系统很奇怪,每天早上都得重启一下应用程序,否则就提示连接数据库失败,他们都不知道该怎么办。
9 E2 o0 h! \4 p+ e9 p2 c我分析说,按照这个错误提示,应该就是连接时间过长了,断开了连接。数据库默认的超时时间是8小时,而你们平时六点下班,下班之后系统就没有人用了,等到第二天早上九点甚至十点才上班,这中间的时间已经超过10个小时了,数据库的连接肯定就会断开了。2 K. Q2 P w' t f) D B4 U9 i
是的,就是超出了超时时间,然后写代码的人也没注意到这个细节,所以才会出现这个问题。
2 L& f$ c, X- f4 O( ^3 V+ m
. j1 h O/ O* w) v把超时时间改得长一点,问题就解决了。, L; c1 G0 A% ]. m( V" X5 |( q1 n
. q$ q0 ]+ X6 k* p8 S! x. ~这种参数其实我们平时不一定能接触到,但是真的遇到问题的时候,知道每个参数的大概用法,不至于让你变成无头苍蝇。* ?; ]' s7 s3 T: w/ ^8 S- {6 u
6 d! n7 E0 }2 Y( ^5 f* O
那除了重新链接,还有别的方式么?因为建立链接还是比较麻烦的。
0 y6 u& x6 T( Z- r9 [+ o- S4 }使用长连接。% W0 q! x% \, c( e+ \8 R
2 s5 P2 \* G; F- I- z0 W8 L- w
但是这里有个缺点,使用长连接之后,内存会飙得很快,我们知道MySQL在执行过程中临时使用的内存是管理在连接对象里面的。4 v' Y" o5 G* P7 G% m0 C
' l% Y( n" ?- v7 h# ]- s& @1 n只有在链接断开的时候才能得到释放,那如果一直使用长连接,那就会导致OOM(Out Of Memory),会导致MySQL重启,在JVM里面就会导致频繁的Full GC。% S4 q/ p' j2 \- g1 e% m+ p, F
* Z: D; ]) T4 J" D
那你会怎么解决?
S/ S* d- K8 ], X( Z) J' {我一般会定期断开长连接,使用一段时间后,或者程序里面判断执行过一个占用内存比较大的查询后就断开连接,需要的时候重连就好了。
* g! `7 f$ k! C) S3 x5 @, ~* S5 Y
& O4 K9 D6 b- H" B; g( t: z还有别的方法么?你这种感觉不优雅呀小老弟。) \% @9 N1 {) M
执行比较大的一个查询后,执行mysql_reset_connection可以重新初始化连接资源。这个过程相比上面一种会好点,不需要重连,但是会初始化连接的状态。8 {% s; n+ j3 P% o( w, ^% O
$ G, }0 P3 q1 O7 O8 N+ S你了解MySQL的查询缓存么?' N2 R5 D, p% A7 F. I
MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。4 _ r+ C( a8 _- a3 p" d% }
) P5 \: i; |/ A A% _( c3 i( L大家是不是好奇同一条语句在MySQL执行两次,第一次和后面的时间是不一样的,后者明显快一些,这就是因为缓存的存在。& `8 }. `& u E
" b3 f7 P+ V2 F: c他跟Redis一样,只要是你之前执行过的语句,都会在内存里面用key-value形式存储着。8 n' i6 Y& b$ f4 z6 J
8 E$ E5 ?* z7 T0 R) H J( ^查询的时候就会拿着语句先去缓存中查询,如果能够命中就返回缓存的value,如果不命中就执行后面的阶段。) d7 R' I6 `% F4 ?9 Q
3 K$ E; q7 w- E; H9 B* p, ^: A
但是我还是不喜欢用缓存,因为缓存弊大于利。- h% s/ N* W8 V8 N
3 c! @ A; C' M7 e8 H: n$ K
哦?此话怎讲?
5 \- Y) a; l; U: `缓存的失效很容易,只要对表有任何的更新,这个表的所有查询缓存就会全部被清空,就会出现缓存还没使用,就直接被清空了,或者积累了很多缓存准备用来着,但是一个更新打回原形。% |. y, Z1 Z. Q0 H& x' ~
4 z9 M& k& }" E$ ]) a" W K- @
这就导致查询的命中率低的可怕,只有那种只查询不更新的表适用缓存,但是这样的表往往很少存在,一般都是什么配置表之类的。6 H1 ]! R2 d% w0 L' u# j
, M% ?0 k; K3 ?8 L% X那我们查询的时候不想用缓存一般都是怎么操作的,或者是用缓存又怎么操作?
3 ~4 \! ]) s6 B# t' l可以显示调用,把query_cache_type设置成为DEMAND,这样SQL默认不适用缓存,想用缓存就用SQL_CACHE。8 ?9 ?4 l d9 ~2 t# O [
4 U$ V) B! x: E5 t& U9 d有个小技巧就是,我们之前开发的时候,都会去库里看看sql执行时间,但是可能是有缓存的,一般我们就在sql前面使用SQL_NO_CACHE就可以知道真正的查询时间了。
v3 Y. D1 k9 M# @5 q, u% Y
6 P2 i5 K+ [3 n7 t3 ]. ] select SQL_NO_CACHE * from B8 W' Z5 x' D4 N8 g
缓存在MySQL8.0之后就取消了,所以大家现在应该不需要太关注这个问题,主要是我之前用的版本都不高,所以缓存一直有,在《高性能MySQL》书中也看到了一些关于缓存的介绍,就想起来给大家也提一下了。( H. M# \2 l6 |2 t: W% e
, q* {# g, h9 g) k) |, A1 t ]缓存查询完了应该做啥呢?* L7 _% Y6 k; ?- r6 R+ s4 f
在缓存没有命中的情况下,就开始执行语句了,你写的语句有没有语法错误,这是接下来MySQL比较关心的点。
" }; I7 F, v/ E6 f& m% v
( {2 Y6 u6 z& f$ h7 [2 q3 a那他会怎么做呢?会先做词法分析,你的语句有这么多单词、空格,MySQL就需要识别每个字符串所代表的是什么,是关键字,还是表名,还是列名等等。
" X* [ S& k- E. }3 @ A4 j3 Q: \2 A
然后就开始语法分析,根据词法分析的结果,语法分析会判断你sql的对错,错了会提醒你的,并且会提示你哪里错了。
2 E9 X# n. z7 v% o5 v0 Z+ W1 Z
, P I2 l/ U4 O5 } l% w4 P分析没错之后就进入下一步,优化器。
; ^9 Z7 N L$ L# c. q7 ~) }$ V& t. J
4 L& I( u" X9 p! s8 C% Y主要是优化什么呢?! r- F7 ^7 U) }/ z
优化就比较简单了,因为我们建立表可能会建立很多索引,优化有一步就是要确认使用哪个索引,比如使用你的主键索引,联合索引还是什么索引更好。
w% G& \7 _2 ], G0 V
1 g2 T2 d3 i+ r# |' u3 D还有就是对执行顺序进行优化,条件那么多,先查哪个表,还是先关联,会出现很多方案,最后由优化器决定选用哪种方案。" `, b# [* W* ]8 v2 |
$ m. V4 ]; N, m: K. i# J
最后就是执行了,执行就交给执行器去做。
2 i9 j8 z. h# Q6 |
7 m, S' M0 B! _2 n, v第一步可能就是权限的判断,其实这里我不确定的一个点就是,我接触的公司很多都是自研的线上查询系统,我们是不能用Navicat直连线上库,只能去网页操作,那表的权限是在MySQL层做的,还是系统做的,我猜应该是系统层做的,MySQL可能默认就全开放了,只是我们 不知道ip。! B% S4 B6 A& N+ t2 t0 ^ B$ p9 I+ a
/ I/ V: L1 w& u9 ]- P6 c0 \4 w
有知道的小伙伴也可以在公众号【三太子敖丙】去加我微信跟我说。+ R. ]( I: ]3 p& W/ U' \
! R; b) r3 \8 ^$ h/ W+ B
执行的时候,就一行一行的去判断是否满足条件,有索引的执行起来可能就好点,一行行的判断就像是接口都提前在引擎定义好了,所以他比较快。
' n% e( V5 D# d! i( e5 C/ A0 F- P
数据库的慢日志有个rows_examined字段,扫描多少行可以看到,还有explain也可以看到执行计划,我们扫描了多少行。& X0 b& x5 T( u( \5 G
+ M) t7 b' i" Y; q可以小伙子,基础大致框架还是了解得很清楚的,我们下次深入了解下,索引和部分机制。
# d6 Q; K5 R4 T ? [8 v, P% O好的,我们下次见。. a; ~5 z; w$ n3 K
7 h; u W' B7 v: e8 e* r% L总结6 r6 c$ M( ?& m4 X
' b: O: k8 D, [
基本上我把MySQL的逻辑架构的东西都简单聊了一遍,当然你去自信了解的话,你会发现其实里面还有很多细节的,我只是说了一些常见的问题,这还是阿里丁奇学长的《MySQL实战》的思路。
( V2 e! v0 P7 Y& G) }- X3 y) k" Q2 @, H8 O! t4 ?6 {. z
我自己在MySQL方面更多的可能就是理论知识了,还做不到深入了解的地步,大家如果有机会一定要深入的去学习一下。
7 q, o7 \) O; Z+ d————————————————. s5 ]/ X- L! Z% [4 X! A. E5 g
版权声明:本文为CSDN博主「敖 丙」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。$ D6 p( d, E$ L; \9 \/ ` p! A
原文链接:https://blog.csdn.net/qq_35190492/article/details/104203466
3 t2 l) G7 Y! r' M/ G; O# L6 Q! I/ i( ?$ U4 r% F6 C
( }# c+ ]! k) M( \ |
zan
|