🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 常见MySQL问题 **什么影响了数据库查询速度** 影响数据库查询速度的四个因素 风险分析 QPS: QueriesPerSecond意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。 TPS:是 TransactionsPerSecond的缩写,也就是事务数/秒。它是软件测试结果的测量单位。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。网站性能测试指标详解,更多看这篇文章。 Tips:最好不要在主库上数据库备份,大型活动前取消这样的计划。 1、效率低下的 sql:超高的 QPS与 TPS。 2、大量的并发:数据连接数被占满( max\_connection默认 100,一般把连接数设置得大一些)。 并发量 : 同一时刻数据库服务器处理的请求数量 3、超高的 CPU使用率:CPU资源耗尽出现宕机。 4、磁盘 IO:磁盘 IO性能突然下降、大量消耗磁盘性能的计划任务。解决:更快磁盘设备、调整计划任务、做好磁盘维护。 网卡流量:如何避免无法连接数据库的情况 1、减少从服务器的数量(从服务器会从主服务器复制日志) 2、进行分级缓存(避免前端大量缓存失效) 3、避免使用 select 进行查询 4、分离业务网络和服务器网络 大表带来的问题(重要) 1.4.1 大表的特点 1、记录行数巨大,单表超千万 2、表数据文件巨大,超过 10个 G 大表的危害 1、慢查询:很难在短时间内过滤出需要的数据 查询字区分度低 -> 要在大数据量的表中筛选出来其中一部分数据会产生大量的磁盘 io -> 降低磁盘效率 2.对 DDL影响: 建立索引需要很长时间: MySQL-v=5.5 建立索引会造成主从延迟( mysql建立索引,先在组上执行,再在库上执行) 修改表结构需要长时间的锁表:会造成长时间的主从延迟(‘480秒延迟’) 如何处理数据库上的大表 分库分表把一张大表分成多个小表 难点: 1、分表主键的选择 2、分表后跨分区数据的查询和统计 **大事务带来的问题(重要) 1、 什么是事务** 事务是数据库系统区别于其他一切文件系统的重要特性之一 事务是一组具有原子性的SQL语句,或是一个独立的工作单元 事务要求符合:原子性、一致性、隔离性、持久性 2、事务的 ACID属性 1、原子性( atomicity):全部成功,全部回滚失败。银行存取款。 2、一致性(consistent):银行转账的总金额不变。3、隔离性(isolation): **隔离性等级:** 未提交读( READ UNCOMMITED) 脏读,两个事务之间互相可见;已提交读( READ COMMITED)符合隔离性的基本概念,一个事务进行时,其它已提交的事物对于该事务是可见的,即可以获取其它事务提交的数据。可重复读( REPEATABLE READ) InnoDB的默认隔离等级。事务进行时,其它所有事务对其不可见,即多次执行读,得到的结果是一样的!可串行化( SERIALIZABLE) 在读取的每一行数据上都加锁,会造成大量的锁超时和锁征用,严格数据一致性且没有并发是可使用。 查看系统的事务隔离级别: show variables like’%iso%’;开启一个新事务: begin;提交一个事务: commit;修改事物的隔离级别: setsession tx\_isolation=‘read-committed’;推荐:面试问烂的 MySQL 四种隔离级别,看完吊打面试官!关注Java技术栈微信公众号,在后台回复关键字:mysql,可以获取更多栈长整理的MySQL技术干货。 4、持久性( DURABILITY):从数据库的角度的持久性,磁盘损坏就不行了 redolog机制保证事务更新的一致性和持久性 **大事务** 运行时间长,操作数据比较多的事务; 风险:锁定数据太多,回滚时间长,执行时间长。 1、锁定太多数据,造成大量阻塞和锁超时; 2、回滚时所需时间比较长,且数据仍然会处于锁定; 3、如果执行时间长,将造成主从延迟,因为只有当主服务器全部执行完写入日志时,从服务器才会开始进行同步,造成延迟。关注Java技术栈微信公众号,在后台回复关键字:mysql,可以获取更多栈长整理的MySQL技术干货。 解决思路: 1、避免一次处理太多数据,可以分批次处理; 2、移出不必要的 SELECT操作,保证事务中只有必要的写操作。 **什么影响了MySQL性能(非常重要)** 2.1 影响性能的几个方面 1、服务器硬件。 2、服务器系统(系统参数优化)。 3、存储引擎。MyISAM:不支持事务,表级锁。InnoDB: 支持事务,支持行级锁,事务 ACID。 4、数据库参数配置。 5、 数据库结构设计和SQL语句。(重点优化) 2.2 MySQL体系结构 分三层:客户端->服务层->存储引擎 1、 MySQL是插件式的存储引擎,其中存储引擎分很多种。只要实现符合mysql存储引擎的接口,可以开发自己的存储引擎! 2、所有跨存储引擎的功能都是在服务层实现的。 3、MySQL的存储引擎是针对表的,不是针对库的。也就是说在一个数据库中可以使用不同的存储引擎。但是不建议这样做。 2.3 InnoDB存储引擎 MySQL5.5及之后版本默认的存储引擎:InnoDB。 2.3.1 InnoDB使用表空间进行数据存储。 show variables like’innodb\_file\_per\_table 如果innodbfileper\_table 为 ON 将建立独立的表空间,文件为tablename.ibd; 如果innodbfileper\_table 为 OFF 将数据存储到系统的共享表空间,文件为ibdataX(X为从1开始的整数); .frm :是服务器层面产生的文件,类似服务器层的数据字典,记录表结构。 2.3.2 (MySQL5.5默认)系统表空间与( MySQL5.6及以后默认)独立表空间 1、系统表空间无法简单的收缩文件大小,造成空间浪费,并会产生大量的磁盘碎片。 2、独立表空间可以通过 optimeze table 收缩系统文件,不需要重启服务器也不会影响对表的正常访问。 3、如果对多个表进行刷新时,实际上是顺序进行的,会产生IO瓶颈。 4、独立表空间可以同时向多个文件刷新数据。 强烈建立对Innodb 使用独立表空间,优化什么的更方便,可控。 2.3.3 系统表空间的表转移到独立表空间中的方法 1、使用mysqldump 导出所有数据库数据(存储过程、触发器、计划任务一起都要导出 )可以在从服务器上操作。 2、停止MYsql 服务器,修改参数(my.cnf加入innodbfileper\_table),并删除Inoodb相关文件(可以重建Data目录)。 3、重启MYSQL,并重建Innodb系统表空间。 4、 重新导入数据。 或者 Altertable 同样可以的转移,但是无法回收系统表空间中占用的空间。 2.4 InnoDB存储引擎的特性 2.4.1 特性一:事务性存储引擎及两个特殊日志类型:Redo Log 和 Undo Log 1、 Innodb 是一种事务性存储引擎。 2、完全支持事务的 ACID特性。3、支持事务所需要的两个特殊日志类型:RedoLog 和 UndoLog Redo Log:实现事务的持久性(已提交的事务)。Undo Log:未提交的事务,独立于表空间,需要随机访问,可以存储在高性能io设备上。 Undo日志记录某数据被修改前的值,可以用来在事务失败时进行 rollback;Redo日志记录某数据块被修改后的值,可以用来恢复未写入 data file的已成功事务更新的数据。 2.4.2 特性二:支持行级锁 1、InnoDB支持行级锁。 2、行级锁可以最大程度地支持并发。 3、行级锁是由存储引擎层实现的。 2.5 什么是锁 2.5.1 锁 锁的主要作用是管理共享资源的并发访问 锁用于实现事务的隔离性 2.5.2 锁类型 **2.5.3 锁的粒度** MySQL的事务支持不是绑定在MySQL服务器本身, 而是与存储引擎相关 表级锁 行级锁 将table\_name加表级锁命令:locktable table\_name write; 写锁会阻塞其它用户对该表的‘读写’操作,直到写锁被释放:unlock tables; 1、锁的开销越大,粒度越小,并发度越高。2、表级锁通常是在服务器层实现的。3、行级锁是存储引擎层实现的。innodb的锁机制,服务器层是不知道的 2.5.4 阻塞和死锁 1、阻塞是由于资源不足引起的排队等待现象。 2、死锁是由于两个对象在拥有一份资源的情况下申请另一份资源,而另一份资源恰好又是这两对象正持有的,导致两对象无法完成操作,且所持资源无法释放。 **2.6 如何选择正确的存储引擎** 参考条件: 1、事务 2、备份( Innobd免费在线备份) 3、崩溃恢复 4、存储引擎的特有特性 总结: nnodb大法好。注意: 别使用混合存储引擎,比如回滚会出问题在线热备问题。 **2.7 配置参数** 2.7.1 内存配置相关参数 确定可以使用的内存上限。 内存的使用上限不能超过物理内存,否则容易造成内存溢出;(对于32位操作系统,MySQL只能试用3G以下的内存。37 个 MySQL 数据库小技巧,推荐看一下。关注Java技术栈微信公众号,在后台回复关键字:mysql,可以获取更多栈长整理的MySQL技术干货。 确定MySQL的每个连接 单独使用的内存。 sort\_buffer\_size 定义了每个线程排序缓存区的大小,MySQL在有查询、需要做排序操作时才会为每个缓冲区分配内存(直接分配该参数的全部内存); join\_buffer\_size 定义了每个线程所使用的连接缓冲区的大小,如果一个查询关联了多张表,MySQL会为每张表分配一个连接缓冲,导致一个查询产生了多个连接缓冲; read\_buffer\_size 定义了当对一张MyISAM进行全表扫描时所分配读缓冲池大小,MySQL有查询需要时会为其分配内存,其必须是4k的倍数; read\_rnd\_buffer\_size 索引缓冲区大小,MySQL有查询需要时会为其分配内存,只会分配需要的大小。 注意:以上四个参数是为一个线程分配的,如果有100个连接,那么需要×100。 MySQL数据库实例: MySQL是单进程多线程(而oracle是多进程),也就是说 MySQL实例在系统上表现就是一个服务进程,即进程; MySQL实例是线程和内存组成,实例才是真正用于操作数据库文件的; 一般情况下一个实例操作一个或多个数据库;集群情况下多个实例操作一个或多个数据库。 如何为缓存池分配内存: Innodb\_buffer\_pool\_size 定义了Innodb所使用缓存池的大小,对其性能十分重要,必须足够大,但是过大时,使得Innodb 关闭时候需要更多时间把脏页从缓冲池中刷新到磁盘中; 总内存-(每个线程所需要的内存\*连接数)- 统保留内存 key\_buffer\_size 定义了MyISAM所使用的缓存池的大小,由于数据是依赖存储操作系统缓存的,所以要为操作系统预留更大的内存空间; select sum(index\_length) from information\_schema.talbes where engine=‘myisam’ 注意:即使开发使用的表全部是Innodb表,也要为MyISAM预留内存,因为MySQL系统使用的表仍然是MyISAM表。 max\_connections 控制允许的最大连接数, 一般2000更大。不要使用外键约束保证数据的完整性 **2.8 性能优化顺序** 库结构设计和SQL语句 数据库存储引擎的选择和参数配置 系统选择及优化 硬件升级 **你目前接触的mysql版本是什么?除了官方版本,还接触过其他的mysql分支版本嘛?** 三个流行MySQL分支:Drizzle、MariaDB和Percona Server(包括XtraDB引擎) MariaDB不仅是mysql的替代品,主要还是创新和提高mysql自有技术。 新功能介绍 multi-source replication 多源复制 表的并行复制 galera cluster集群 spider水平分片 tokuDB存储引擎 XtraDB是innodb存储引擎的增强版,可用来更好地发挥最新的计算机硬件系统性能,还包含在高性能模式下的新特性。它可以向下兼容,因为它是在innodb基础上构建,所以他有更多的指标和扩展功能。而且它在cpu多核的条件下,可以更好地使用内存,时数据库性能提到更高! Drizzle与mysql的差别就比较大了,并且不能兼容,如果想运行此环境,就需要重写一些代码了! **mysql主要的存储引擎myisam和innodb的不同之处?** 事务的支持不同(innodb支持事务,myisam不支持事务) 锁粒度(innodb行锁应用,myisam表锁) 存储空间(innodb既缓存索引文件又缓存数据文件,myisam只能缓存索引文件) 存储结构 (myisam:数据文件的扩展名为.MYD myData ,索引文件的扩展名是.MYI myIndex) (innodb:所有的表都保存在同一个数据文件里面 即为.Ibd) 5. 统计记录行数 (myisam:保存有表的总行数,select count(\*) from table;会直接取出出该值) (innodb:没有保存表的总行数,select count(\*) from table;就会遍历整个表,消耗相当大) **两种最长使用的 Innodb 和 Myisam 区别** 1. 事务的支持不同(innodb支持事务,myisam不支持事务) 2. 锁粒度(innodb行锁应用,myisam表锁) 3. 存储空间(innodb既缓存索引文件又缓存数据文件,myisam只能缓存索引文件) 4. 存储结构 (myisam:数据文件的扩展名为.MYD myData ,索引文件的扩展名是.MYI myIndex) (innodb:所有的表都保存在同一个数据文件里面 即为.Ibd) 5. 统计记录行数 (myisam:保存有表的总行数,select count(*) from table;会直接取出出该值) (innodb:没有保存表的总行数,select count(*) from table;就会遍历整个表,消耗相当大) **Innodb的体系结构简单介绍一下?** 谈及到innodb的体系结构,首先要考虑mysql的体系结构,分为两部分mysql的server层和存储引擎层 先要跟面试官聊清楚mysql的整体方向,然后再去涉及innodb体系结构 建议从三方面介绍innodb体系结构:内存----线程-----磁盘 内存中包含insert\_buffer,data\_buffer,index\_buffer,redo\_log\_buffer,double\_write 内存刷新到磁盘的机制,redo,脏页,binlog的刷新条件 各种线程的作用,master\_thread,purge\_thread,redo log thread,read thread,write thread,page cleaner thread 磁盘中存放着数据文件,redo log,undo log,binlog **mysql有哪些索引类型:** 数据结构角度上可以分:B+tree索引,hash索引,fulltext索引(innodb,myisam都支持) 存储角度上可以分:聚集索引,非聚集索引 逻辑角度上可以分:primary key,normal key,单列,复合,覆盖索引 mysql binlog有几种格式: 1. statement 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能 缺点:当使用一些特殊函数的时候,或者跨库操作的时候容易丢失数据 注:在生产中不建议使用 2. row 优点:清晰记录每行的数据信息,不会出现跨库丢数据的情况 缺点:内容当记录到日志中的时候,都将以每行记录的修改来记录,但就会产生大量的binlog,对于网络开销也比较大 注:生产中推荐使用 3. mixed 是mysql5.1的时候,一个过渡版本,DDL语句会记录成statement,DML会记录row。 注:生产中不建议使用 **mysql主从复制的具体原理 是什么?** 主服务器把数据更新记录到二进制日志中,从服务器通过io thread向主库发起binlog请求,主服务器通过IO dump thread把二进制日志传递给从库,从库通过io thread记录到自己的中继日志中。然后再通过sql thread应用中继日志中sql的内容。 **数据库中双一是什么?** sync\_binlog=1 innodb\_flush\_log\_at\_trx\_commit=1 innodb\_flush\_log\_at\_trx\_commit和sync\_binlog 两个参数是控制MySQL 磁盘写入策略以及数据安全性的关键参数 innodb\_flush\_log\_at\_trx\_commit设置为1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且刷到磁盘中去。 sync\_binlog =N (N>0) ,MySQL 在每写 N次 二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中去 **如何监控mysql replication复制延迟?** 可以通过第三方工具 业界中的瑞士×××percona-toolkit中的命令,pt-heartbeat进行主从延迟监控。 传统方法,通过比较主从服务器之间的position号的差异值。 还可以通过查看seconds\_behind\_master估算一下主从延迟时间 **大表DDL语句,如何实施,才能把性能影响降到最低?** 可以通过传统方法导入导出数据,新建一张与原表一样的表结构,把需要执行的ddl语句在无数据的新表执行,然后把老表中的数据导入到新表中,把新表改成老表的名字 通过第三方工具 业界中的瑞士×××percona-toolkit中的命令,pt-online-schema-change进行在线操作 对于新版本的mysql(5.7)可以直接在线online ddl **为什么要为innodb表设置自增列做主键?** 1.使用自增列做主键,写入顺序是自增的,和B+数叶子节点分裂顺序一致 2.表不指定自增列做主键,同时也没有可以被选为主键的唯一索引,InnoDB就会选择内置的rowid作为主键,写入顺序和rowid增长顺序一致 所以InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高 **如何优化一条有问题的sql语句?** 针对sql语句的优化,我们不要上来就回答添加索引,这样显得太不专业。我们可以从如下几个角度去分析 回归到表的设计层面,数据类型选择是否合理 大表碎片的整理是否完善 表的统计信息,是不是准确的 审查表的执行计划,判断字段上面有没有合适的索引 针对索引的选择性,建立合适的索引(就又涉及到大表DDL的操作问题) **服务器负载过高或者网页打开缓慢,简单说说你的优化思路 ?** 首先我们要发现问题的过程,通过操作系统,数据库,程序设计,硬件角度四个维度找到问题所在 找到瓶颈点的位置 制定好优化方案,形成处理问题的体系 体系制定好之后,在测试环境进行优化方案的测试 测试环境如果优化效果很好,再实施到生产环境 做好处理问题的记录 **接触过哪些mysql的主流架构?架构应用中有哪些问题需要考虑?** M-S MHA MM keepalived PXC 共同存在的问题:主从延迟问题的存在,在主库宕机,切换过程中要考虑数据一致性的问题,避免出现主从复制不一致 **什么是死锁?锁等待?如何优化这类问题?通过数据库哪些表可以监控?** 死锁是指两个或多个事务在同一资源上互相占用,并请求加锁时,而导致的恶性循环现象。当多个事务以不同顺序试图加锁同一资源时,就会产生死锁。 锁等待:mysql数据库中,不同session在更新同行数据中,会出现锁等待 重要的三张锁的监控表innodb\_trx,innodb\_locks,innodb\_lock\_waits **处理过mysql哪些案例** 我们可以简单从mysql四个知识模块跟他聊聊mysql体系结构,数据备份恢复,优化,高可用集群架构 **mysql版本的升级** 处理mysql集群的各种坑和问题 根据公司业务类型,设计合理mysql库,表,架构。 定期进行灾备恢复演练 误删除数据之后,恢复数据 简单先从这几个方向说说,每个问题再展开分析。 当然还会有一些人事上面的问题,例如为啥选我们的公司,你觉得你自己的优势是什么?你期望的薪资大概是多少?这些问题,就很简单了。我们只要过了技术面试,这些都不是啥问题了! **MySQL 中的 latin1 是什么字符集?** 这个字符集相信大家都见过,一般在创建数据库的时候会进行设置。它在 Java 中代表的就是 ISO-8859-1。共收录256个字符,是在ASCII 字符集的基础上又扩充了 128 个西欧常用字符(包括德法两国的字母),也可以使用 1 个字节来进行编码。ISO-8859-1 这个字符集在 MySQL 中的别名就是 latin1。 **为什么我们通常推荐使用 utf8mb4 字符集?** 比如当我们存储 emoji 表情时,会出现无法存入的问题。但是没有人从原理上来说为什么会丢失。这个我们可以通过 SHOW CHARSET like ‘utf8%’; 命令查看一下 utf8 和 utf8mb4 的区别。 之所以无法存储的原因就是,UTF-8 编码有可能是两个、三个、四个字节。Emoji 表情是 4 个字节,而 Mysql 的 utf8 编码最多 3 个字节,所以数据插不进去。 **表 xttblog 存在且该表中不存在 name 字段,那么执行 select \* from xttblog where name = ‘业余草’ 肯定会报错,请问是在连接器,分析器,优化器,执行器等哪个阶段报错?** 答案是分析器。因为,连接器是负责处理管理连接,权限验证的;分析器是进行词法分析,语法分析的;优化器是进行语句优化,生成执行计划,选择索引的;执行器是真正执行 SQL 语句的,并返回结果集的。所以,回答分析器才是对的。 **MySQL 5.8 中为什么把查询缓存这一块移除了?** 这个查询缓存,这一块估计很多人都没注意到。新版本的 5.8 版本的 MySQL 数据库已经移除了查询缓存这一块的设计。而且在 5.7 版本中也不推荐使用了。移除的原因是,虽然查询缓存有时候能比较快的返回数据,但是维护起来太麻烦了。而且缓存命中率太低了。如果对应的表有 insert、update、delete 等,那么缓存就得失效。如果查询语句中有函数,则放弃查询缓存。因为函数会设计的计算等有太多的不确定性。还有一些函数根本不能缓存,或没必要缓存。比如,select now() 就不能缓存,再比如,select version() 就没必要缓存。综合考虑,MySQL 把它给移除了。 **1\. 如何设计一个高并发的系统** ① 数据库的优化,包括合理的事务隔离级别、SQL语句优化、索引的优化 ② 使用缓存,尽量减少数据库 IO ③ 分布式数据库、分布式缓存 ④ 服务器的负载均衡 **2\. 锁的优化策略** ① 读写分离 ② 分段加锁 ③ 减少锁持有的时间 ④ 多个线程尽量以相同的顺序去获取资源 等等,这些都不是绝对原则,都要根据情况,比如不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。这部分跟面试官谈了很久 **3\. 索引的底层实现原理和优化** B+树,经过优化的B+树 主要是在所有的叶子结点中增加了指向下一个叶子节点的指针,因此InnoDB建议为大部分表使用默认自增的主键作为主索引。 **4\. 什么情况下设置了索引但无法使用** ① 以“%”开头的LIKE语句,模糊匹配 ② OR语句前后没有同时使用索引 ③ 数据类型出现隐式转化(如varchar不加单引号的话可能会自动转换为int型) **5\. SQL语句的优化** order by要怎么处理 alter尽量将多次合并为一次 insert和delete也需要合并 **6\. 实践中如何优化MySQL** 我当时是按以下四条依次回答的,他们四条从效果上第一条影响最大,后面越来越小。 ① SQL语句及索引的优化 ② 数据库表结构的优化 ③ 系统配置的优化 ④ 硬件的优化 **8\. sql注入的主要特点** 变种极多,攻击简单,危害极大 **9\. sql注入的主要危害** 未经授权操作数据库的数据 恶意纂改网页 私自添加系统账号或者是数据库使用者账号 网页挂木马 **10、优化数据库的方法** · 选取最适用的字段属性,尽可能减少定义字段宽度,尽量把字段设置NOTNULL,例如’省份’、'性别’最好适用ENUM · 使用连接(JOIN)来代替子查询 · 适用联合(UNION)来代替手动创建的临时表 · 事务处理 · 锁定表、优化事务处理 · 适用外键,优化锁定表 · 建立索引 · 优化查询语句 **11\. 简单描述mysql中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响(从读写两方面)** 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。 普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。 普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。也就是说,唯一索引可以保证数据记录的唯一性。 主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字 PRIMARY KEY 来创建。 索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引,这就是联合索引。 索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件。 **12.数据库中的事务是什么?** 事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使只有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务将回滚,该事务所有操作的影响都将取消。ACID 四大特性,原子性、隔离性、一致性、持久性。 **13.了解XSS攻击吗?如何防止?** XSS是跨站脚本攻击,首先是利用跨站脚本漏洞以一个特权模式去执行攻击者构造的脚本,然后利用不安全的Activex控件执行恶意的行为。 使用htmlspecialchars()函数对提交的内容进行过滤,使字符串里面的特殊符号实体化。 14.SQL注入漏洞产生的原因?如何防止? SQL注入产生的原因:程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。 防止SQL注入的方式: 开启配置文件中的magic\_quotes\_gpc 和 magic\_quotes\_runtime设置 执行sql语句时使用addslashes进行sql语句转换 Sql语句书写尽量不要省略双引号和单引号。 过滤掉sql语句中的一些关键词:update、insert、delete、select、 \* 。 提高数据库表和字段的命名技巧,对一些重要的字段根据程序的特点命名,取不易被猜到的。 Php配置文件中设置register\_globals为off,关闭全局变量注册 控制错误信息,不要在浏览器上输出错误信息,将错误信息写到日志文件中。 **15、 对于关系型数据库而言,索引是相当重要的概念,请回答有关索引的几个问题:** a)、索引的目的是什么? 快速访问数据表中的特定信息,提高检索速度 创建唯一性索引,保证数据库表中每一行数据的唯一性。 加速表和表之间的连接 使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间 b)、索引对数据库系统的负面影响是什么? 负面影响: 创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改、的时候索引也要动态维护,这样就降低了数据的维护速度。 c)、为数据表建立索引的原则有哪些? 在最频繁使用的、用以缩小查询范围的字段上建立索引。 在频繁使用的、需要排序的字段上建立索引 d)、 什么情况下不宜建立索引? 对于查询中很少涉及的列或者重复值比较多的列,不宜建立索引。 对于一些特殊的数据类型,不宜建立索引,比如文本字段(text)等 **16、 简述在MySQL数据库中MyISAM和InnoDB的区别** 区别于其他数据库的最重要的特点就是其插件式的表存储引擎。切记:存储引擎是基于表的,而不是数据库。 **InnoDB与MyISAM的区别:** InnoDB存储引擎: 主要面向OLTP(Online Transaction Processing,在线事务处理)方面的应用,是第一个完整支持ACID事务的存储引擎(BDB第一个支持事务的存储引擎,已经停止开发)。 特点: · 行锁设计、支持外键,支持事务,支持并发,锁粒度是支持mvcc得行级锁; MyISAM存储引擎: 是MySQL官方提供的存储引擎,主要面向OLAP(Online Analytical Processing,在线分析处理)方面的应用。 特点: 不支持事务,锁粒度是支持并发插入得表级锁,支持表所和全文索引。操作速度快,不能读写操作太频繁; **17、 解释MySQL外连接、内连接与自连接的区别** 先说什么是交叉连接: 交叉连接又叫笛卡尔积,它是指不使用任何条件,直接将一个表的所有记录和另一个表中的所有记录一一匹配。 内连接 则是只有条件的交叉连接,根据某个条件筛选出符合条件的记录,不符合条件的记录不会出现在结果集中,即内连接只连接匹配的行。 外连接 其结果集中不仅包含符合连接条件的行,而且还会包括左表、右表或两个表中的所有数据行,这三种情况依次称之为左外连接,右外连接,和全外连接。 左外连接,也称左连接,左表为主表,左表中的所有记录都会出现在结果集中,对于那些在右表中并没有匹配的记录,仍然要显示,右边对应的那些字段值以NULL来填充。 右外连接,也称右连接,右表为主表,右表中的所有记录都会出现在结果集中。左连接和右连接可以互换,MySQL目前还不支持全外连接。 **18、 写出三种以上MySQL数据库存储引擎的名称(提示:不区分大小写)** MyISAM、InnoDB、BDB(BerkeleyDB)、Merge、Memory(Heap)、Example、Federated、 Archive、CSV、Blackhole、MaxDB 等等十几个引擎 **19、Myql中的事务回滚机制概述** 事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位,事务回滚是指将该事务已经完成的对数据库的更新操作撤销。 要同时修改数据库中两个不同表时,如果它们不是一个事务的话,当第一个表修改完,可能第二个表修改过程中出现了异常而没能修改,此时就只有第二个表依旧是未修改之前的状态,而第一个表已经被修改完毕。而当你把它们设定为一个事务的时候,当第一个表修改完,第二表修改出现异常而没能修改,第一个表和第二个表都要回到未修改的状态,这就是所谓的事务回滚 **20\. SQL语言包括哪几部分?每部分都有哪些操作关键字?** 答:SQL语言包括数据定义(DDL)、数据操纵(DML),数据控制(DCL)和数据查询(DQL)四个部分。 数据定义:Create Table,Alter Table,Drop Table, Craete/Drop Index等 数据操纵:Select ,insert,update,delete, 数据控制:grant,revoke 数据查询:select **21\. 完整性约束包括哪些?** 答:数据完整性(Data Integrity)是指数据的精确(Accuracy)和可靠性(Reliability)。 分为以下四类: 1. 实体完整性:规定表的每一行在表中是惟一的实体。 2. 域完整性:是指表中的列必须满足某种特定的数据类型约束,其中约束又包括取值范围、精度等规定。 3. 参照完整性:是指两个表的主关键字和外关键字的数据应一致,保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据库中扩散。 4. 用户定义的完整性:不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。用户定义的完整性即是针对某个特定关系数据库的约束条件,它反映某一具体应用必须满足的语义要求。 与表有关的约束:包括列约束(NOT NULL(非空约束))和表约束(PRIMARY KEY、foreign key、check、UNIQUE) 。 **22\. 什么是事务?及其特性?** 答:事务:是一系列的数据库操作,是数据库应用的基本逻辑单位。 事务特性: (1)原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。 (2)一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态 (3)隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务, (4) 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。 或者这样理解: 事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。 **23\. 什么是锁?** 答:数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。 ~~~ 加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。 ~~~ 基本锁类型:锁包括行级锁和表级锁 **24\. 什么叫视图?游标是什么?** 答:视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,视图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。 游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。 **25\. 什么是存储过程?用什么来调用?** 答:存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。可以用一个命令对象来调用存储过程。 **26\. 索引的作用?和它的优点缺点是什么?** 答:索引就一种特殊的查询表,数据库的搜索引擎可以利用它加速对数据的检索。它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。索引可以是唯一的,创建索引允许指定单个列或者是多个列。缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。 **27\. 如何通俗地理解三个范式?** 答:第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解; 第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性; 第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。。 范式化设计优缺点: 优点: 可以尽量得减少数据冗余,使得更新快,体积小 缺点: 对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引优化 反范式化: 优点:可以减少表得关联,可以更好得进行索引优化 缺点:数据冗余以及数据异常,数据得修改需要更多的成本 **28\. 什么是基本表?什么是视图?** 答:基本表是本身独立存在的表,在 SQL 中一个关系就对应一个表。 视图是从一个或几个基本表导出的表。视图本身不独立存储在数据库中,是一个虚表 **29\. 试述视图的优点?** 答:(1) 视图能够简化用户的操作 (2) 视图使用户能以多种角度看待同一数据; (3) 视图为数据库提供了一定程度的逻辑独立性; (4) 视图能够对机密数据提供安全保护。 **30\. NULL是什么意思** 答:NULL这个值表示UNKNOWN(未知):它不表示“”(空字符串)。对NULL这个值的任何比较都会生产一个NULL值。您不能把任何值与一个 NULL值进行比较,并在逻辑上希望获得一个答案。 使用IS NULL来进行NULL判断 **31\. 主键、外键和索引的区别?** 主键、外键和索引的区别 定义: 主键–唯一标识一条记录,不能有重复的,不允许为空 外键–表的外键是另一表的主键, 外键可以有重复的, 可以是空值 索引–该字段没有重复值,但可以有一个空值 作用: 主键–用来保证数据完整性 外键–用来和其他表建立联系用的 索引–是提高查询排序的速度 个数: 主键–主键只能有一个 外键–一个表可以有多个外键 索引–一个表可以有多个唯一索引 **32\. 你可以用什么来确保表格里的字段只接受特定范围里的值?** 答:Check限制,它在数据库表格里被定义,用来限制输入该列的值。 触发器也可以被用来限制数据库表格里的字段能够接受的值,但是这种办法要求触发器在表格里被定义,这可能会在某些情况下影响到性能。 **33\. 说说对SQL语句优化有哪些方法?(选择几条)** (1)Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。 (2)用EXISTS替代IN、用NOT EXISTS替代NOT IN。 (3) 避免在索引列上使用计算 (4)避免在索引列上使用IS NULL和IS NOT NULL (5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 (6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描 (7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描 **34\. SQL语句中‘相关子查询’与‘非相关子查询’有什么区别?** 答:子查询:嵌套在其他查询中的查询称之。 子查询又称内部,而包含子查询的语句称之外部查询(又称主查询)。 所有的子查询可以分为两类,即相关子查询和非相关子查询 (1)非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。 (2)相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。 故非相关子查询比相关子查询效率高 **35\. char和varchar的区别?** 答:是一种固定长度的类型,varchar则是一种可变长度的类型,它们的区别是: char(M)类型的数据列里,每个值都占用M个字节,如果某个长度小于M,MySQL就会在它的右边用空格字符补足.(在检索操作中那些填补出来的空格字符将被去掉)在varchar(M)类型的数据列里,每个值只占用刚好够用的字节再加上一个用来记录其长度的字节(即总长度为L+1字节). varchar的适用场景: 字符串列的最大长度比平均长度大很多 字符串很少被更新,容易产生存储碎片 使用多字节字符集存储字符串 Char的场景: ~~~ 存储具有近似得长度(md5值,身份证,手机号),长度比较短小得字符串(因为varchar需要额外空间记录字符串长度),更适合经常更新得字符串,更新时不会出现页分裂得情况,避免出现存储碎片,获得更好的io性能 ~~~ **36\. Mysql 的存储引擎,myisam和innodb的区别。** 答:简单的表达: MyISAM 是非事务的存储引擎;适合用于频繁查询的应用;表锁,不会出现死锁;适合小数据,小并发 innodb是支持事务的存储引擎;合于插入和更新操作比较多的应用;设计合理的话是行锁(最大区别就在锁的级别上);适合大数据,大并发。 **37\. 数据表类型有哪些** 答:MyISAM、InnoDB、HEAP、BOB,ARCHIVE,CSV等。 ~~~ MyISAM:成熟、稳定、易于管理,快速读取。一些功能不支持(事务等),表级锁。 InnoDB:支持事务、外键等特性、数据行锁定。空间占用大,不支持全文索引等。 ~~~ **38\. MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化?** a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。 b. 选择合适的表字段数据类型和存储引擎,适当的添加索引。 c. mysql库主从读写分离。 d. 找规律分表,减少单表中的数据量提高查询速度。 e。添加缓存机制,比如memcached,apc等。 f. 不经常改动的页面,生成静态页面。 g. 书写高效率的SQL。比如 SELECT \* FROM TABEL 改为 SELECT field\_1, field\_2, field\_3 FROM TABLE. **39\. 对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题?** 答:a. 确认服务器是否能支撑当前访问量。 b. 优化数据库访问。 c. 禁止外部访问链接(盗链), 比如图片盗链。 d. 控制文件下载。 e. 使用不同主机分流。 f. 使用浏览统计软件,了解访问量,有针对性的进行优化。 **40、如何进行SQL优化?(关于后边的解释同学们可以进行理解,到时根据自己的理解把大体意思说出来即可)** (1)选择正确的存储引擎 以 MySQL为例,包括有两个存储引擎 MyISAM 和 InnoDB,每个引擎都有利有弊。 MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(\*) 这类的计算是超快无比的。 InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。但是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。 (2)优化字段的数据类型 记住一个原则,越小的列会越快。如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多。当然,你也需要留够足够的扩展空间。 (3)为搜索字段添加索引 索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索,那么最好是为其建立索引,除非你要搜索的字段是大的文本字段,那应该建立全文索引。 (4)避免使用Select*从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。即使你要查询数据表的所有字段,也尽量不要用*通配符,善用内置提供的字段排除定义也许能给带来更多的便利。 (5)使用 ENUM 而不是 VARCHAR ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。例如,性别、民族、部门和状态之类的这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。 (6)尽可能的使用 NOT NULL 除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。 NULL其实需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。 当然,这里并不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。 (7)固定长度的表会更快 如果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”。 例如,表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。 固定长度的表会提高性能,因为MySQL搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键。并且,固定长度的表也更容易被缓存和重建。不过,唯一的副作用是,固定长度的字段会浪费一些空间,因为定长的字段无论你用不用,他都是要分配那么多的空间。 **41,为表中得字段选择合适得数据类型(物理设计)** 字段类型优先级: 整形>date,time>enum,char>varchar>blob,text 优先考虑数字类型,其次是日期或者二进制类型,最后是字符串类型,同级别得数据类型,应该优先选择占用空间小的数据类型 **42:存储时期** Datatime:以 YYYY-MM-DD HH:MM:SS 格式存储时期时间,精确到秒,占用8个字节得存储空间,datatime类型与时区无关 Timestamp:以时间戳格式存储,占用4个字节,范围小1970-1-1到2038-1-19,显示依赖于所指定得时区,默认在第一个列行的数据修改时可以自动得修改timestamp列得值 Date:(生日)占用得字节数比使用字符串.datatime.int储存要少,使用date只需要3个字节,存储日期月份,还可以利用日期时间函数进行日期间得计算 Time:存储时间部分得数据 注意:不要使用字符串类型来存储日期时间数据(通常比字符串占用得储存空间小,在进行查找过滤可以利用日期得函数) 使用int存储日期时间不如使用timestamp类型 **问题1:char、varchar的区别是什么?** varchar是变长而char的长度是固定的。如果你的内容是固定大小的,你会得到更好的性能。 **问题2: TRUNCATE和DELETE的区别是什么?** DELETE命令从一个表中删除某一行,或多行,TRUNCATE命令永久地从表中删除每一行。 **问题3:什么是触发器,MySQL中都有哪些触发器?** 触发器是指一段代码,当触发某个事件时,自动执行这些代码。在MySQL数据库中有如下六种触发器: 1、Before Insert 2、After Insert 3、Before Update 4、After Update 5、Before Delete 6、After Delete **问题4:FLOAT和DOUBLE的区别是什么?** FLOAT类型数据可以存储至多8位十进制数,并在内存中占4字节。 DOUBLE类型数据可以存储至多18位十进制数,并在内存中占8字节。 **问题5:如何在MySQL种获取当前日期?** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510185912235.) **问题6:如何查询第n高的工资?** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510185918739.) **问题7:请写出下面MySQL数据类型表达的意义(int(0)、char(16)、varchar(16)、datetime、text)** int(0)表示数据是INT类型,长度是0、char(16)表示固定长度字符串,长度为16、varchar(16)表示可变长度字符串,长度为16、datetime表示时间类型、text表示字符串类型,能存储大字符串,最多存储65535字节数据) **问题8:请说明InnoDB和MyISAM的区别** 1、InnoDB支持事务,MyISAM不支持; 2、InnoDB数据存储在共享表空间,MyISAM数据存储在文件中; 3、InnoDB支持行级锁,MyISAM只支持表锁; 4、InnoDB支持崩溃后的恢复,MyISAM不支持; 5、InnoDB支持外键,MyISAM不支持; 6、InnoDB不支持全文索引,MyISAM支持全文索引; **问题9:innodb引擎的特性** 1、插入缓冲(insert buffer) 2、二次写(double write) 3、自适应哈希索引(ahi) 4、预读(read ahead) **问题10:请列举3个以上表引擎** InnoDB、MyISAM、Memory **问题11:请说明varchar和text的区别** 1、varchar可指定字符数,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n255),text是实际字符数+2个字节。 2、text类型不能有默认值。 3、varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text,在都创建索引的情况下,text的索引几乎不起作用。 4、查询text需要创建临时表。 **问题12:varchar(50)中50的含义** 最多存放50个字符,varchar(50)和(200)存储hello所占空间一样,但后者在排序时会消耗更多内存,因为order by col采用fixed\_length计算col长度(memory引擎也一样)。 **问题13:int(20)中20的含义** 是指显示字符的长度,不影响内部存储,只是当定义了ZEROFILL时,前面补多少个 0 **问题14:简单描述MySQL中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响?** 一个表只能有一个主键索引,但是可以有多个唯一索引。 1、主键索引一定是唯一索引,唯一索引不是主键索引。 2、主键可以与外键构成参照完整性约束,防止数据不一致。 3、联合索引:将多个列组合在一起创建索引,可以覆盖多个列。(也叫复合索引,组合索引) 4、外键索引:只有InnoDB类型的表才可以使用外键索引,保证数据的一致性、完整性、和实现级联操作(基本不用)。 5、全文索引:MySQL自带的全文索引只能用于MyISAM,并且只能对英文进行全文检索 (基本不用) **问题15:创建MySQL联合索引应该注意什么?** 需遵循前缀原则 **问题16:列值为NULL时,查询是否会用到索引?** 在MySQL里NULL值的列也是走索引的。当然,如果计划对列进行索引,就要尽量避免把它设置为可空,MySQL难以优化引用了可空列的查询,它会使索引、索引统计和值更加复杂。 **问题17:以下语句是否会应用索引:SELECT FROM users WHERE YEAR(adddate) < 2019;**\* 不会,因为只要列涉及到运算,MySQL就不会使用索引。 **问题18:MyISAM索引实现?** MyISAM存储引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。MyISAM的索引方式也叫做非聚簇索引的,之所以这么称呼是为了与InnoDB的聚簇索引区分。 **问题19:MyISAM索引与InnoDB索引的区别?** 1、InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。 2、InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。 3、MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。 4、InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。 **问题20:有A(id,sex,par,c1,c2),B(id,age,c1,c2)两张表,其中A.id与B.id关联,现在要求写出一条SQL语句,将B中age>50的记录的c1,c2更新到A表中同一记录中的c1,c2字段中** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190028914.) **问题21 :MySQL的关联查询语句你会那些?** 六种关联查询 1、交叉连接(CROSS JOIN) 2、内连接(INNER JOIN) 3、外连接(LEFT JOIN/RIGHT JOIN) 4、联合查询(UNION与UNION ALL) 5、全连接(FULL JOIN) 6、交叉连接(CROSS JOIN) **内连接分为三类** 1、等值连接:ON[A.id=B.id](http://a.id%3Db.id/) 2、不等值连接:ON[A.id](http://a.id/)\>[B.id](http://b.id/) 3、自连接:SELECT \* FROM A T1 INNER JOIN A T2 ON T1.id=T2.pid **外连接(LEFT JOIN/RIGHT JOIN)** 1、左外连接:LEFT OUTER JOIN, 以左表为主,先查询出左表,按照ON后的关联条件匹配右表,没有匹配到的用NULL填充,可以简写成LEFT JOIN 2、右外连接:RIGHT OUTER JOIN, 以右表为主,先查询出右表,按照ON后的关联条件匹配左表,没有匹配到的用NULL填充,可以简写成RIGHT JOIN **联合查询(UNION与UNION ALL)** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190056137.) 1、就是把多个结果集集中在一起,UNION前的结果为基准,需要注意的是联合查询的列数要相等,相同的记录行会合并 2、如果使用UNION ALL,不会合并重复的记录行 3、效率 UNION 高于 UNION ALL **全连接(FULL JOIN)** 1、MySQL不支持全连接 2、可以使用LEFT JOIN 和UNION和RIGHT JOIN联合使用 **嵌套查询** 用一条SQL语句得结果作为另外一条SQL语句得条件,效率不好把握 解题方法 根据考题要搞清楚表的结果和多表之间的关系,根据想要的结果思考使用那种关联方式,通常把要查询的列先写出来,然后分析这些列都属于哪些表,才考虑使用关联查询 **问题22:UNION与UNION ALL的区别?** 1、如果使用UNION ALL,不会合并重复的记录行 2、效率 UNION 高于 UNION ALL **问题23:一个6亿的表a,一个3亿的表b,通过外键tid关联,你如何最快的查询出满足条件的第50000到第50200中的这200条数据记录。** 1、如果A表TID是自增长,并且是连续的,B表的ID为索引 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190124967.) 2、如果A表的TID不是连续的,那么就需要使用覆盖索引.TID要么是主键,要么是辅助索引,B表ID也需要有索引。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190130921.) 问题24:拷贝表( 拷贝数据, 源表名:a 目标表名:b) **问题25:Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 查询没学过“叶平”老师课的同学的学号、姓名** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190144987.) 问题26:随机取出10条数据![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190150160.) **问题27:请简述项目中优化SQL语句执行效率的方法,从哪些方面,SQL语句性能如何分析?** **考点分析:** 这道题主要考察的是查找分析SQL语句查询速度慢的方法 **延伸考点:** 1、优化查询过程中的数据访问 2、优化长难的查询语句 3、优化特定类型的查询语句 **如何查找查询速度慢的原因** 记录慢查询日志,分析查询日志,不要直接打开慢查询日志进行分析,这样比较浪费时间和精力,可以使用pt-query-digest工具进行分析 **使用show profile** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190215718.) **使用show status** show status会返回一些计数器,show global status会查看所有服务器级别的所有计数 有时根据这些计数,可以推测出哪些操作代价较高或者消耗时间多 show processlist 观察是否有大量线程处于不正常的状态或特征 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190221245.) 最常问的MySQL面试题五——每个开发人员都应该知道 **使用explain** 分析单条SQL语句 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190233289.) **优化查询过程中的数据访问** 1、访问数据太多导致查询性能下降 2、确定应用程序是否在检索大量超过需要的数据,可能是太多行或列 3、确认MySQL服务器是否在分析大量不必要的数据行 4、避免犯如下SQL语句错误 5、查询不需要的数据。解决办法:使用limit解决 6、多表关联返回全部列。解决办法:指定列名 7、总是返回全部列。解决办法:避免使用SELECT \* 8、重复查询相同的数据。解决办法:可以缓存数据,下次直接读取缓存 9、是否在扫描额外的记录。解决办法: 10、使用explain进行分析,如果发现查询需要扫描大量的数据,但只返回少数的行,可以通过如下技巧去优化: 11、使用索引覆盖扫描,把所有的列都放到索引中,这样存储引擎不需要回表获取对应行就可以返回结果。 12、改变数据库和表的结构,修改数据表范式 13、重写SQL语句,让优化器可以以更优的方式执行查询。 **优化长难的查询语句** 1、一个复杂查询还是多个简单查询 2、MySQL内部每秒能扫描内存中上百万行数据,相比之下,响应数据给客户端就要慢得多 3、使用尽可能小的查询是好的,但是有时将一个大的查询分解为多个小的查询是很有必要的。 4、切分查询 5、将一个大的查询分为多个小的相同的查询 6、一次性删除1000万的数据要比一次删除1万,暂停一会的方案更加损耗服务器开销。 7、分解关联查询,让缓存的效率更高。 8、执行单个查询可以减少锁的竞争。 9、在应用层做关联更容易对数据库进行拆分。 10、查询效率会有大幅提升。 11、较少冗余记录的查询。 **优化特定类型的查询语句** 1、count(\*)会忽略所有的列,直接统计所有列数,不要使用count(列名) 2、MyISAM中,没有任何where条件的count(\*)非常快。 3、当有where条件时,MyISAM的count统计不一定比其它引擎快。 4、可以使用explain查询近似值,用近似值替代count(\*) 5、增加汇总表 6、使用缓存 **优化关联查询** 1、确定ON或者USING子句中是否有索引。 2、确保GROUP BY和ORDER BY只有一个表中的列,这样MySQL才有可能使用索引。 **优化子查询** 1、用关联查询替代 2、优化GROUP BY和DISTINCT 3、这两种查询据可以使用索引来优化,是最有效的优化方法 4、关联查询中,使用标识列分组的效率更高 5、如果不需要ORDER BY,进行GROUP BY时加ORDER BY NULL,MySQL不会再进行文件排序。 6、WITH ROLLUP超级聚合,可以挪到应用程序处理 **优化LIMIT分页** 1、LIMIT偏移量大的时候,查询效率较低 2、可以记录上次查询的最大ID,下次查询时直接根据该ID来查询 优化UNION查询 UNION ALL的效率高于UNION 优化WHERE子句 解题方法 对于此类考题,先说明如何定位低效SQL语句,然后根据SQL语句可能低效的原因做排查,先从索引着手,如果索引没有问题,考虑以上几个方面,数据访问的问题,长难查询句的问题还是一些特定类型优化的问题,逐一回答。 **问题28:SQL语句优化的一些方法?** 1、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190306490.) 3、应尽量避免在 where 子句中使用!=或<>操作符,否则引擎将放弃使用索引而进行全表扫描。 4、应尽量避免在 where 子句中使用or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190315751.) 5、in 和 not in 也要慎用,否则会导致全表扫描,如: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190320775.) 6、下面的查询也将导致全表扫描:select id from t where name like ‘%李%’若要提高效率,可以考虑全文检索。 7、 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190327906.) 8、应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190334190.) 9、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190510190340508.) 10、不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引