接上篇!!!
9. 主键使用自增ID还是UUID?
推荐使用自增ID,不要使用UUID。
因为在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后排列即可,如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,然后导致产生很多的内存碎片,进而造成插入性能的下降。
总之,在数据量大一些的情况下,用自增主键性能会好一些。
关于主键是聚簇索引,如果没有主键,InnoDB会选择一个唯一键来作为聚簇索引,如果没有唯一键,会生成一个隐式的主键。
10. 字段为什么要求定义为not null?
null值会占用更多的字节,且会在程序中造成很多与预期不符的情况。
11. 如果要存储用户的密码散列,应该使用什么字段进行存储?
密码散列,盐,用户身份证号等固定长度的字符串应该使用char而不是varchar来存储,这样可以节省空间且提高检索效率。
12. 优化查询过程中的数据访问
(1)访问数据太多导致查询性能下降
(2)确定应用程序是否在检索大量超过需要的数据,可能是太多行或列
(3)确认MySQL服务器是否在分析大量不必要的数据行
(4)避免犯如下SQL语句错误
(5)查询不需要的数据。解决办法:使用limit解决
(6)多表关联返回全部列。解决办法:指定列名
(7)总是返回全部列。解决办法:避免使用SELECT *
(8)重复查询相同的数据。解决办法:可以缓存数据,下次直接读取缓存
(9)是否在扫描额外的记录。解决办法:
(10)使用explain进行分析,如果发现查询需要扫描大量的数据,但只返回少数的行,可以通过如下技巧去优化:
(11)使用索引覆盖扫描,把所有的列都放到索引中,这样存储引擎不需要回表获取对应行就可以返回结果。
(12)改变数据库和表的结构,修改数据表范式
(13)重写SQL语句,让优化器可以以更优的方式执行查询。
13. 优化长难的查询语句
(1)一个复杂查询还是多个简单查询
(2)MySQL内部每秒能扫描内存中上百万行数据,相比之下,响应数据给客户端就要慢得多
(3)使用尽可能小的查询是好的,但是有时将一个大的查询分解为多个小的查询是很有必要的。
(4)切分查询
(5)将一个大的查询分为多个小的相同的查询
(6)一次性删除1000万的数据要比一次删除1万,暂停一会的方案更加损耗服务器开销。
(7)分解关联查询,让缓存的效率更高。
(8)执行单个查询可以减少锁的竞争。
(9)在应用层做关联更容易对数据库进行拆分。
(10)查询效率会有大幅提升。
(11)较少冗余记录的查询。
14. 优化特定类型的查询语句
(1)count(*)会忽略所有的列,直接统计所有列数,不要使用count(列名)
(2)MyISAM中,没有任何where条件的count(*)非常快。
(3)当有where条件时,MyISAM的count统计不一定比其它引擎快。
(4)可以使用explain查询近似值,用近似值替代count(*)
(5)增加汇总表
(6)使用缓存
15. 优化关联查询
(1)确定ON或者USING子句中是否有索引。
(2)确保GROUP BY和ORDER BY只有一个表中的列,这样MySQL才有可能使用索引。
16. 优化子查询
(1)用关联查询替代
(2)优化GROUP BY和DISTINCT
(3)这两种查询据可以使用索引来优化,是最有效的优化方法
(4)关联查询中,使用标识列分组的效率更高
(5)如果不需要ORDER BY,进行GROUP BY时加ORDER BY NULL,MySQL不会再进行文件排序。
(6)WITH ROLLUP超级聚合,可以挪到应用程序处理
17. 优化LIMIT分页
(1)LIMIT偏移量大的时候,查询效率较低
(2)可以记录上次查询的最大ID,下次查询时直接根据该ID来查询
18. 优化UNION查询
(1)UNION ALL的效率高于UNION
19. 优化WHERE子句
解题方法
对于此类考题,先说明如何定位低效SQL语句,然后根据SQL语句可能低效的原因做排查,先从索引着手,如果索引没有问题,考虑以上几个方面,数据访问的问题,长难查询句的问题还是一些特定类型优化的问题,逐一回答。
最后,小编分类整理了许多java进阶学习材料和BAT面试给热爱IT行业的你,如果需要资料的请转发此文章后再私聊小编回复【java】就能领取2019年java进阶学习资料和BAT面试题以及《Effective Java》(第3版)电子版书籍。也可以加群:712263501领取海量学习资料进行学习。