语句规范 |
原因 |
所有关键字、函数必须大写,变量小写 所有标点符号使用英文状态下的半角输入方式 |
尽可能在每个平台统一格式,关键字大写变量小写有利于提高辨识度 |
不使用反向查询,如not in/like |
反向查询无法使用索引,导致全表扫描,全表扫描导致buffer pool利用率降低 |
避免使用存储过程、触发器、UDF、events等 |
让数据库做最擅长的事,降低业务耦合度,为sacle out、sharding留有余地,避开BUG |
避免在语句执行中进行数学运算 |
MySQL不擅长数学运算和逻辑判断,使用数学运算时无法使用索引 |
尽可能使用
|
减少与数据库的交互次数,尽量采用批量SQL语句,合并多个相同的操作到一起,可以提高处理效率
INSERT语句必须指定字段列表,建议禁止使用 INSERT INTO TABLE() |
INSERT语句使用batch提交 |
NSERT INTO table VALUES(),(),()……,values的个数不超过500 |
禁止在where语句中使用ike关键字 |
会导致全表扫描,无法使用索引,影响性能 |
尽可能避免在where语句中判断NULL值 |
会导致全表扫描,无法使用索引,影响性能 |
使用EXPLAIN诊断,避免生成临时表 |
EXPLAIN语句(在MySQL客户端中执行)可以获得MySQL如何执行SELECT语句的信息。通过对SELECT语句执行EXPLAIN,可以知晓MySQL执行该SELECT语句时是否使用了索引、全表扫描、临时表、排序等信息。尽量避免MySQL进行全表扫描、使用临时表、排序等 |
不使用select *
SELECT语句只获取需要的字段 |
消耗CPU和IO、消耗网络带宽 无法使用覆盖索引 减少表结构变更带来的影响 因为大,select/join 可能生成临时表 |
使用in代替or,in的值不超过1000个 当in的值过多时,建议使用EXIST进行代替 |
MySql中,IN()先将自己列表中的数据进行排序,然后通过二分查找的方式确定列的值是否在IN()的列表中,时间复杂度是O(logn)。 如果换成OR操作,则时间复杂度是O(n)。 对于IN()的列表中有大量取值的时候,用IN()替换OR操作将会更快 |
禁止使用order by rand() |
会把表中所有符合条件的数据装载到内存中,然后在内存中对所有数据根据随机生成的值进行排序,并且可能会对每一行都生成一个随机值,如果满足条件的数据集非常大,就会消耗大量的CPU和IO及内存资源。
推荐在程序中获取一个随机值,然后从数据库中获取数据的方式 |
在明显不会有重复值时使用UNION ALL而不是UNION |
UNION会把两个结果集的所有数据放到临时表中后再进行去重操作 UNION ALL不会再对结果集进行去重操作 |
不使用单条SQL语句同时更新多个表 |
|
SQL中禁止出现now()、rand()、sysdate()、current_user()等不确定结果的函数 |
|
注
数据更新建议使用二级索引先查询出主键,再根据主键进行数据更新