我是刘小言,一个努力搞技术的程序员。
今天给讲讲数据库优化方面的面试题,面试官问你数据库优化,一般就是sql调优,调优一般是查询慢sql的优化,我一般遇到慢sql,首先会想到索引有没有发挥自己的作用,比如某个查询接响应慢,你就相当于找到这个慢sql,把sql语句复制到navicat【sql使用工具】,然后利用explain【解释】要么你点击
,要么explain+SQL语句来模拟优化器执行SQL查询语句,从而知道mysql是如何处理sql语句的。
Column | Meaning |
id | The SELECT identifier |
select_type | The SELECT type |
table | The table for the output row |
partitions | The matching partitions |
type | The join type |
possible_keys | The possible indexes to choose |
key | The index actually chosen |
key_len | The length of the chosen key |
ref | The columns compared to the index |
rows | Estimate of rows to be examined |
filtered | Percentage of rows filtered by table condition |
extra | Additional information |
我就不对于explain各参数展开详细介绍了,一般百度搜一搜都可以了解到。
我们主要看两个参数type、key、extra
type显示的是访问类型,访问类型表示我是以何种方式去访问我们的数据,最容易想的是全表扫描,直接暴力的遍历一张表去寻找需要的数据,效率非常低下,访问的类型有很多,效率从最好到最坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般情况下,得保证查询至少达到range级别,最好能达到ref
key表示实际使用的索引,如果为null,则没有使用索引,查询中若使用了覆盖索引,则该索引和查询的select字段重叠。
extra包含额外的信息。一般你需要怎么优化都可以做个参考
面试回答的时候可以这样说:
平常我在公司优化sql是先定位慢sql,然后explain执行检查是否使用有效索引,尽量往索引上引,如果所以未生效就修改sql语句,如果union all 代替union等一些操作,我曾遇到过三个特别大的表,每个表有几十万的数据信息,功能需要三个表进行关联查询数据信息,但三表关联怎么调还是在5s外或者在4-5s,我们查询响应一般要控制在2s以内,所以这明显不符合要求,当我发现两表关联的时候,查询时间在1s内,我利用了代码方法里同时进行两表关联和单表查询,等两个查询都获取到数据后,我进行for循环处理组装数据信息,该接口操作时间在多次测试验证后,都控制在了1.5s内,有效的解决了响应慢的问题。
事实上不仅仅只有优化sql,还有就是对于不怎么动的数据信息放入缓存中,设置一个合适的过期时间,也能很好的解决页响应的问题。
另外需要了解的是索引设计的原则:在进行索引设计的时候,应该保证索引字段占用的空间越小越好,这只是一个大的方向,还有一些细节点需要注意下:
1、适合索引的列是出现在where字句中的列,或者连接子句中指定的列
2、基数较小的表,索引效果差,没必要创建索引
3、在选择索引列的时候,越短越好,可以指定某些列的一部分,没必要用全部字段的值
4、不要给表中的每一个字段都创建索引,并不是索引越多越好
5、定义有外键的数据列一定要创建索引
6、更新频繁的字段不要有索引
7、创建索引的列不要过多,可以创建组合索引,但是组合索引的列的个数不建议太多
8、大文本、大对象不要创建索引
在几百万数据的查询,需要优化方面是:
1、限定数据的范围:避免不带任何限制数据范围条件的查询语句。
2、读写分离:主库负责写,从库负责读。
3、垂直分表:将一个表按照字段分成多个表,每个表存储其中一部分字段。
4、水平分表:在同一个数据库内,把一个表的数据按照一定规则拆分到多个表中。
5、对单表进行优化:对表中的字段、索引、查询SQL进行优化。
6、添加缓存
除了我遇到以上数据库优化面试题外,再额外赠送一个数据库笔试题:




