MySQL数据库基础知识及优化

L表

R表

  • 左外连接 :select L.`*`,R.`*` from L left join R onL.b=R.b

  • 右外连接:select L.`*`,R.`*` from L right join R onL.b=R.b

  • 内连接:select L.`*`,R.`*` from L inner join R on L.b=R.b

  • 交叉连接:select L.`*`,R.`*` from L,R

mysql中in和exists的区别? **

==========================

in和exists一般用于子查询。

  • 使用exists时会先进行外表查询,将查询到的每行数据带入到内表查询中看是否满足条件;使用in一般会先进行内表查询获取结果集,然后对外表查询匹配结果集,返回数据。

  • in在内表查询或者外表查询过程中都会用到索引。

  • exists仅在内表查询时会用到索引

  • 一般来说,当子查询的结果集比较大,外表较小使用exist效率更高;当子查询寻得结果集较小,外表较大时,使用in效率更高。

  • 对于not in和not exists,not exists效率比not in的效率高,与子查询的结果集无关,因为not in对于内外表都进行了全表扫描,没有使用到索引。not exists的子查询中可以用到表上的索引。

varchar和char的区别? ***

========================

  • varchar表示变长,char表示长度固定。当所插入的字符超过他们的长度时,在严格模式下,会拒绝插入并提示错误信息,在一般模式下,会截取后插入。如char(5),无论插入的字符长度是多少,长度都是5,插入字符长度小于5,则用空格补充。对于varchar(5),如果插入的字符长度小于5,则存储的字符长度就是插入字符的长度,不会填充。

  • 存储容量不同,对于char来说,最多能存放的字符个数为255。对于varchar,最多能存放的字符个数是65532。

  • 存储速度不同,char长度固定,存储速度会比varchar快一些,但在空间上会占用额外的空间,属于一种空间换时间的策略。而varchar空间利用率会高些,但存储速度慢,属于一种时间换空间的策略。

MySQL中int(10)和char(10)和varchar(10)的区别? ***

==============================================

int(10)中的10表示的是显示数据的长度,而char(10)和varchar(10)表示的是存储数据的大小。

drop、delete和truncate的区别? **

===============================

dropdeletetruncate速度快逐行删除,慢较快类型DDLDMLDDL回滚不可回滚可回滚不可回滚删除内容删除整个表,数据行、索引都会被删除表结构还在,删除表的一部分或全部数据表结构还在,删除表的全部数据

一般来讲,删除整个表,使用drop,删除表的部分数据使用delete,保留表结构删除表的全部数据使用truncate。

UNION和UNION ALL的区别? **

==========================

union和union all的作用都是将两个结果集合并到一起。

  • union会对结果去重并排序,union all直接直接返回合并后的结果,不去重也不进行排序。

  • union all的性能比union性能好。

什么是临时表,什么时候会使用到临时表,什么时候删除临时表? *

===================================

MySQL在执行SQL语句的时候会临时创建一些存储中间结果集的表,这种表被称为临时表,临时表只对当前连接可见,在连接关闭后,临时表会被删除并释放空间。

临时表主要分为内存临时表和磁盘临时表两种。内存临时表使用的是MEMORY存储引擎,磁盘临时表使用的是MyISAM存储引擎。

一般在以下几种情况中会使用到临时表:

  • FROM中的子查询

  • DISTINCT查询并加上ORDER BY

  • ORDER BY和GROUP BY的子句不一样时会产生临时表

  • 使用UNION查询会产生临时表

大表数据查询如何进行优化? ***

=====================

  • 索引优化

  • SQL语句优化

  • 水平拆分

  • 垂直拆分

  • 建立中间表

  • 使用缓存技术

  • 固定长度的表访问起来更快

  • 越小的列访问越快

了解慢日志查询吗?统计过慢查询吗?对慢查询如何优化? ***

==================================

慢查询一般用于记录执行时间超过某个临界值的SQL语句的日志。

相关参数:

  • slow_query_log:是否开启慢日志查询,1表示开启,0表示关闭。

  • slow_query_log_file:MySQL数据库慢查询日志存储路径。

  • long_query_time:慢查询阈值,当SQL语句查询时间大于阈值,会被记录在日志上。

  • log_queries_not_using_indexes:未使用索引的查询会被记录到慢查询日志中。

  • log_output:日志存储方式。“FILE”表示将日志存入文件。“TABLE”表示将日志存入数据库。

如何对慢查询进行优化?

  • 分析语句的执行计划,查看SQL语句的索引是否命中

  • 优化数据库的结构,将字段很多的表分解成多个表,或者考虑建立中间表。

  • 优化LIMIT分页。

为什么要设置主键? **

================

主键是唯一区分表中每一行的唯一标识,如果没有主键,更新或者删除表中特定的行会很困难,因为不能唯一准确地标识某一行。

主键一般用自增ID还是UUID? **

=======================

使用自增ID的好处:

  • 字段长度较uuid会小很多。

  • 数据库自动编号,按顺序存放,利于检索

  • 无需担心主键重复问题

使用自增ID的缺点:

  • 因为是自增,在某些业务场景下,容易被其他人查到业务量。

  • 发生数据迁移时,或者表合并时会非常麻烦

  • 在高并发的场景下,竞争自增锁会降低数据库的吞吐能力

UUID:通用唯一标识码,UUID是基于当前时间、计数器和硬件标识等数据计算生成的。

使用UUID的优点:

  • 唯一标识,不会考虑重复问题,在数据拆分、合并时也能达到全局的唯一性。

  • 可以在应用层生成,提高数据库的吞吐能力。

  • 无需担心业务量泄露的问题。

使用UUID的缺点:

  • 因为UUID是随机生成的,所以会发生随机IO,影响插入速度,并且会造成硬盘的使用率较低。

  • UUID占用空间较大,建立的索引越多,造成的影响越大。

  • UUID之间比较大小较自增ID慢不少,影响查询速度。

最后说下结论,一般情况MySQL推荐使用自增ID。因为在MySQL的InnoDB存储引擎中,主键索引是一种聚簇索引,主键索引的B+树的叶子节点按照顺序存储了主键值及数据,如果主键索引是自增ID,只需要按顺序往后排列即可,如果是UUID,ID是随机生成的,在数据插入时会造成大量的数据移动,产生大量的内存碎片,造成插入性能的下降。

字段为什么要设置成not null? **

=========================

首先说一点,NULL和空值是不一样的,空值是不占用空间的,而NULL是占用空间的,所以字段设为NOT NULL后仍然可以插入空值。

字段设置成not null主要有以下几点原因:

  • NULL值会影响一些函数的统计,如count,遇到NULL值,这条记录不会统计在内。

  • B树不存储NULL,所以索引用不到NULL,会造成第一点中说的统计不到的问题。

  • NOT IN子查询在有NULL值的情况下返回的结果都是空值。例如user表如下idusername0zhangsan1lisi2nullselect * from `user` where username NOT IN (select username from `user` where id != 0),这条查询语句应该查到zhangsan这条数据,但是结果显示为null。

  • MySQL在进行比较的时候,NULL会参与字段的比较,因为NULL是一种比较特殊的数据类型,数据库在处理时需要进行特数处理,增加了数据库处理记录的复杂性。

如何优化查询过程中的数据访问? ***

=======================

从减少数据访问方面考虑:

  • 正确使用索引,尽量做到索引覆盖

  • 优化SQL执行计划

从返回更少的数据方面考虑:

  • 数据分页处理

  • 只返回需要的字段

从减少服务器CPU开销方面考虑:

  • 合理使用排序

  • 减少比较的操作

  • 复杂运算在客户端处理

从增加资源方面考虑:

  • 客户端多进程并行访问

  • 数据库并行处理

如何优化长难的查询语句? **

===================

  • 将一个大的查询分解为多个小的查询

  • 分解关联查询,使缓存的效率更高

如何优化LIMIT分页? **

===================

  • 在LIMIT偏移量较大的时候,查询效率会变低,可以记录每次取出的最大ID,下次查询时可以利用ID进行查询

  • 建立复合索引

如何优化UNION查询 **

==================

如果不需要对结果集进行去重或者排序建议使用UNION ALL,会好一些。

如何优化WHERE子句 ***

===================

  • 不要在where子句中使用!=和<>进行不等于判断,这样会导致放弃索引进行全表扫描。

  • 不要在where子句中使用null或空值判断,尽量设置字段为not null。

  • 尽量使用union all代替or

  • 在where和order by涉及的列建立索引

  • 尽量减少使用in或者not in,会进行全表扫描

  • 在where子句中使用参数会导致全表扫描

  • 避免在where子句中对字段及进行表达式或者函数操作会导致存储引擎放弃索引进而全表扫描

SQL语句执行的很慢原因是什么? ***

========================

  • 如果SQL语句只是偶尔执行很慢,可能是执行的时候遇到了锁,也可能是redo log日志写满了,要将redo log中的数据同步到磁盘中去。

  • 如果SQL语句一直都很慢,可能是字段上没有索引或者字段有索引但是没用上索引。

SQL语句的执行顺序? *

=================

SELECT DISTINCT

select_list

FROM

left_table

LEFT JOIN

right_table ON join_condition

WHERE

where_condition

GROUP BY

group_by_list

HAVING

having_condition

ORDER BY

order_by_condition

执行顺序如下:

  • FROM:对SQL语句执行查询时,首先对关键字两边的表以笛卡尔积的形式执行连接,并产生一个虚表V1。虚表就是视图,数据会来自多张表的执行结果。

  • ON:对FROM连接的结果进行ON过滤,并创建虚表V2

  • JOIN:将ON过滤后的左表添加进来,并创建新的虚拟表V3

  • WHERE:对虚拟表V3进行WHERE筛选,创建虚拟表V4

  • GROUP BY:对V4中的记录进行分组操作,创建虚拟表V5

  • HAVING:对V5进行过滤,创建虚拟表V6

  • SELECT:将V6中的结果按照SELECT进行筛选,创建虚拟表V7

  • DISTINCT:对V7表中的结果进行去重操作,创建虚拟表V8,如果使用了GROUP BY子句则无需使用DISTINCT,因为分组的时候是将列中唯一的值分成一组,并且每组只返回一行记录,所以所有的记录都h是不同的。

  • ORDER BY:对V8表中的结果进行排序。

数据库优化

=========

大表如何优化? ***

===============

面试题总结

其它面试题(springboot、mybatis、并发、java中高级面试总结等)

OUP BY:对V4中的记录进行分组操作,创建虚拟表V5

  • HAVING:对V5进行过滤,创建虚拟表V6

  • SELECT:将V6中的结果按照SELECT进行筛选,创建虚拟表V7

  • DISTINCT:对V7表中的结果进行去重操作,创建虚拟表V8,如果使用了GROUP BY子句则无需使用DISTINCT,因为分组的时候是将列中唯一的值分成一组,并且每组只返回一行记录,所以所有的记录都h是不同的。

  • ORDER BY:对V8表中的结果进行排序。

数据库优化

=========

大表如何优化? ***

===============

面试题总结

其它面试题(springboot、mybatis、并发、java中高级面试总结等)

[外链图片转存中…(img-JyR3CulW-1714426481215)]

[外链图片转存中…(img-NsVK2x0g-1714426481215)]

[外链图片转存中…(img-kQNm0ytc-1714426481216)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 12
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值