面试中常见的SQL优化问题

一、表的设计
0、必须使用默认的InnoDB存储引擎--支持事务、行级锁、并发性能好、CPU及内存缓存页优化使得资源利用率高
1、表和字段使用中文注释--便于后人理解
2、使用默认utf8mb4字符集--标准、万国码、无乱码风险、无需转码
3、禁止使用触发器、视图、存储过程和event
4、禁止使用外键--外键导致表之间的耦合,update和delete操作都会涉及相关表,影响性能
--架构方向:对数据库性能影响较大的特性少用;应将计算集中在服务层,解放数据库CPU;数据库擅长索引和存储,勿让数据库背负重负
5、禁止存大文件或者照片--在数据库里存储URI
字段:
6、必须把字段定义为NOT NULL并设置默认值--null值需要更多的存储空间;
字段中有null值的话,name != 'san' 查询结果中不包含name is null的记录
7、禁止使用TEXT/BOLB字段类型--浪费磁盘和内存空间,非必要的大量的大字段查询导致内存命中率降低,影响数据库性能
索引:
8、单表索引控制在5个以内
9、单索引不超过5个字段--超过5个以及起不到有效过滤数据的效果
10、建立组合索引,必须把区分度高的字段放在前边--更加有效的过滤数据
11、数据区分度不大的字段不易使用索引--例如:性别只有男,女,订单状态,每次过滤数据很少




二、SQL查询规范:
1、禁止使用select *,只获取需要的字段--查询很多无用字段,增加CPU/IO/NET消耗;不能有效的利用覆盖索引;增删字段易出bug
2、禁止使用属性的隐式转换select * from customer where phone=123123--会导致全表扫描,不能命中索引
3、禁止在where条件上使用函数和计算
4、禁止负向查询(NOT != <> !< !> MOT IN NOT LIKE)和%开头的like(前导模糊查询)--会导致全表扫描
5、禁止大表使用JOIN查询和子查询--会产生临时表,消耗较多CPU和内存,影响数据库性能
6、在属性上进行计算不能命中索引--如 select * from order where YEAR(date) <= '2017'不能命中索引导致全表扫描
7、复合索引最左前缀--例如user 表建立了(userid,phone)的联合索引
有如下几种写法:
(1)select * from user where userid = ? and phone = ?
(2)select * from user where phone=? and userid= ?
(3)select * from user where phone = ?
(4)select * from user where userid = ?
其中(1)(2)(4)可以命中索引,(3)会导致全表扫描


8、明知道只有一条记录返回,建议加上limit 1








参考文章:http://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=504476631&idx=1&sn=e36a083ef4bfcb33cfbf945cb8a37b79&chksm=3d2d060b0a5a8f1db22f21d24cd92577dbb3abcee08b1dd771e7b27ed1b0997af304561c0ab5&mpshare=1&scene=23&srcid=0920u9JMQ216HlTCCxyiK0j6#rd
http://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=504476256&idx=1&sn=517cda6790e181d0b96e1599f75ad055&chksm=3d2d07bc0a5a8eaa8a7e6e8d639fabc96edeb97aa28a088fc1cb8973d52e4580660f654af826&mpshare=1&scene=23&srcid=0920F8OavtK3XvhwtBpUNJkW#rd

你可能感兴趣的:(SQL优化)