**「理由:」** * 主键一般都要加上的,没有主键的表是没有灵魂的 * 创建时间和更新时间的话,还是建议加上吧,详细审计、跟踪记录,都是有用的。 阿里开发手册也提到这个点,如图 ![](https://www.www.zyiz.net/i/ll/?i=20201216202546370.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70) 8、写完SQL语句,检查where,order by,group by后面的列,多表关联的列是否已加索引,优先考虑组合索引。(SQL性能优化) **「反例:」**
select * from user
where address =‘深圳’ order by age;
![](https://www.www.zyiz.net/i/ll/?i=20201216202628577.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70) **「正例:」**
添加索引
alter table user add index idx_address_age (address,age)
![](https://www.www.zyiz.net/i/ll/?i=20201216202711481.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70) 9、修改或删除重要数据前,要先备份,先备份,先备份(SQL后悔药) 如果要修改或删除数据,在执行SQL前一定要先备份要修改的数据,万一误操作,还能吃口**「后悔药」**~ 10、where后面的字段,留意其数据类型的隐式转换(SQL性能优化) **「反例:」**
//userid 是varchar字符串类型
select * from user where userid =123;
![](https://www.www.zyiz.net/i/ll/?i=20201216202804975.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70) **「正例:」**
select * from user where userid =‘123’;
![](https://www.www.zyiz.net/i/ll/?i=20201216202847893.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70) **「理由:」** 因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为浮点数再做比较,最后导致索引失效 11、尽量把所有列定义为NOT NULL(SQL规范优雅) * **「NOT NULL列更节省空间」**,NULL列需要一个额外字节作为判断是否为 NULL 的标志位。 * **「NULL列需要注意空指针问题」**,NULL列在计算和比较的时候,需要注意空指针问题。 12、修改或者删除SQL,先写WHERE查一下,确认后再补充 delete 或 update(SQL后悔药) 尤其在操作生产的数据时,遇到修改或者删除的SQL,先加个where查询一下,确认OK之后,再执行update或者delete操作 13、减少不必要的字段返回,如使用select <具体字段> 代替 select \* (SQL性能优化) **「反例:」**
select * from employee;
**「正例:」**
select id,name from employee;
理由: * 节省资源、减少网络开销。 * 可能用到覆盖索引,减少回表,提高查询效率。 14、所有表必须使用Innodb存储引擎(SQL规范优雅) Innodb **「支持事务,支持行级锁,更好的恢复性」**,高并发下性能更好,所以呢,没有特殊要求(即Innodb无法满足的功能如:列存储,存储空间数据等)的情况下,所有表必须使用Innodb存储引擎 15、数据库和表的字符集尽量统一使用UTF8(SQL规范优雅) 尽量统一使用UTF8编码 * 可以避免乱码问题 * 可以避免,不同字符集比较转换,导致的索引失效问题 **「如果需要存储表情,那么选择utf8mb4来进行存储,注意它与utf-8编码的区别。」**
begin;
update account set balance =1000000
where name =‘捡田螺的小男孩’;
commit;
16、尽量使用varchar代替 char。(SQL性能优化) **「反例:」**
deptName
char(100) DEFAULT NULL COMMENT ‘部门名称’
**「正例:」**
deptName
varchar(100) DEFAULT NULL COMMENT ‘部门名称’
理由: * 因为首先变长字段存储空间小,可以节省存储空间。 17、如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。(SQL规范优雅) 这个点,是阿里开发手册中,Mysql的规约。你的字段,尤其是表示枚举状态时,如果含义被修改了,或者状态追加时,为了后面更好维护,需要即时更新字段的注释。 18、SQL命令行修改数据,养成begin + commit 事务的习惯(SQL后悔药) **「反例:」**
update account set balance =1000000
where name =‘捡田螺的小男孩’;
**「正例:」**
begin;
update account set balance =1000000
where name =‘捡田螺的小男孩’;
commit;
19、索引命名要规范,主键索引名为 pk\_ 字段名;唯一索引名为 uk \_字段名 ;普通索引名则为 idx \_字段名。(SQL规范优雅) 说明:pk\_即primary key;uk\_即unique key;idx\_即index 的简称。 20、WHERE从句中不对列进行函数转换和表达式计算 假设loginTime加了索引 **「反例:」**
select userId,loginTime
from loginuser
where Date_ADD(loginTime,Interval 7 DAY) >=now();
**「正例:」**
explain select userId,loginTime
from loginuser
where loginTime >= Date_ADD(NOW(),INTERVAL - 7 DAY);
**「理由:」** 索引列上使用mysql的内置函数,索引失效 ![](https://www.www.zyiz.net/i/ll/?i=20201216203319112.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70) 21、如果修改/更新数据过多,考虑批量进行。 **「反例:」**
delete from account limit 100000;
**「正例:」**
我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!
以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目,有需要的朋友点击这里即可免费领取
可以把相关底层代码和要点都看起来。
我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!
以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目,有需要的朋友点击这里即可免费领取
[外链图片转存中…(img-1IzEV1A0-1628296895654)]
[外链图片转存中…(img-wluJdm1n-1628296895656)]