如果要保存IPv4地址,
反例
`ip_address` VARCHAR(15) NOT NULL
正例。
`ip_address` INT UNSIGNED NOT NULL
原因
192.160.98.123
转化为十六进制数是,C0
,A0
,62
,7B
,C0A0627B
转化为十进制数是3231736443。select *
,而是要select具体的字段反例
select * from employee;
正例
select id,name from employee;
原因
limit 1
反例
select id,name from employee where name='jay';
正例
select id,name from employee where name='jay' limit 1;
原因
limit 1
,当一条相关的记录被查询到时,数据库不会继续扫表,而是返回结果where
条件中避免使用or
以下面的user
表为例子,usedId
作为索引。
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userId` int(11) NOT NULL,
`age` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_userId` (`userId`)
)
如果你想查询用户id为1或者,年龄为18的用户,你可能使用以下sql
语句。
反例
select * from user where userid = 1 or age = 18;
正例
select * from user where userid=1
union all
select * from user where age = 18;
// 或者使用两条独立的sql
select * from user where userid=1;
select * from user where age = 18;
原因
or
的使用可能导致全表扫表,导致没有使用索引当使用limit
去分页的时候,offset
的值可能非常大,查询的效率就会下降。
反例
select id,name,age from employee limit 10000,10;
正例
// 方案1
select id,name from employee where id>10000 limit 10;
// 方案2
select id,name from employee order by id limit 10000,10;
原因
order by
和主键索引,也能提高查询效率LIKE
语句模糊查询的时候,如果不是前缀查询,会使索引失效。
反例
select userId,name from user where userId like '%Patrick';
正例
select userId,name from user where userId like 'Patrick%';
where
语句中避免使用!=
或<>
反例
select age,name from user where age <>18;
正例
select age,name from user where age > 18;
select age,name from user where age < 18;
!=
或者<>
有可能使索引失效反例
for(User u :list){
INSERT into user(name,age) values(#name#,#age#)
}
正例
// 500个插入,将插入语句拼接成一个sql
<foreach collection="list" item="item" index="index" separator=",">
(#{item.name},#{item.age})
</foreach>
原因
distinct
的使用distinct
一般用来过滤重复的记录。当时查询单个或者少量的字段时,能够提高查询的效率。
但是,当对很多字段使用distinct
时,会降低查询的效率。
反例
SELECT DISTINCT * from user;
正例
select DISTINCT name from user;
原因
distinct
时,CPU需要花费大量的时间进行去重。反例
KEY `idx_userId` (`userId`)
KEY `idx_userId_age` (`userId`,`age`)
正例
KEY `idx_userId_age` (`userId`,`age`)
原因
delete
语句当删除大量的数据时,因为删除记录需要对表进行加锁。删除大量的数据,需要占用较多的时间,从而会导致其他事务处于等待锁的阶段,从而超时。
反例
// 一次删除1百万条记录
delete from user where id <100000;
// 在一个循环里面删除单条记录
for(User user:list){ delete from user; }
正例
// 批量删除,每次删除500条记录
delete product where id>=500 and id<1000;
NULL
,而是使用默认值,反例
select * from user where age is not null;
正例
select * from user where age>0; // 将0作为默认值
原因
NULL
会占用空间,并且MySQL对含有NULL
的列很难进行查询优化。union all
替代union
反例
select * from user where userid=1
union
select * from user where age = 10
正例
select * from user where userid=1
union all
select * from user where age = 10
原因
union
, 在shuMySQL会对查询结果进行去重操作,而去重操作涉及到排序,这可能会影响性能union all
没有对查询结果进行去重。如果确定查询结果没有重复的记录,可以使用union all
而不是union
explain
去分析你的sql语句explain select * from user where userid = 10086 or age =18;
我的博客:https:www.liangyaopei.com