1. 不要把 select 子句写成 select *
坏处1:返回的字段太多了;
坏处2:数据库执行的时候需要先查询表结构,得到表结构后再改造sql语句,将 * 换成字段,然后才能再去执行sql语句,这样数据库执行起来不够高效。
2. 谨慎使用模糊查询
SELECT ename FROM t_emp WHERE ename LIKE '%s%';
假如ename字段设置了索引,后面like表达式开头写了%,那么数据库就会略过ename这个索引,执行全表扫描。这是因为开头的%可以代表任意多的字符,所以数据库不知道怎么到索引的二叉树中查找数据
如果开头不写%,那么数据库是可以根据索引来查询数据库的,sql如下:
SELECT ename FROM t_emp WHERE ename LIKE 's%';
3. 对 order by 排序的字段设置索引,可以大大加快数据库执行的速度
SELECT ename FROM t_emp ORDER BY deptno
因为索引是二叉树机制,所以对ORDER BY后面的字段设置索引后,排序就很快了。
4. 少用 is null 和 is not null
is null 和 is not null 这两个表达式都会让数据库跳过索引,执行全表扫描。因为null值无法排序
SELECT ename FROM t_emp WHERE comm IS NOT NULL;
上面sql语句可以用下面的sql语句替换,可以将comm设置为非空约束,用-1代表空值
SELECT ename FROM t_emp WHERE comm >= 0;
SELECT ename FROM t_emp WHERE comm = -1;
5. 尽量少用 != 运算符
还是因为索引是二叉树构成的,判断xxx等于xxx,xxx大于xxx或者xxx小于xxx,表达式都可以利用二叉树快速定位到数据,但是 != 是不行的。
SELECT ename FROM t_emp WHERE deptno != 20;
可以改成
SELECT ename FROM t_emp WHERE deptno < 20 OR deptno > 20;
6. 尽量少用 or 运算符,因为逻辑或运算符也会让数据库跳过索引
or 运算符之前的表达式会利用索引,但是之后的表达式就会跳过索引,执行全表扫描
SELECT ename FROM t_emp WHERE deptno = 20 OR deptno = 30;
deptno = 20 会利用索引,但是deptno = 30就不会,而是全表扫描。
可以改成下面sql语句进行优化,使用 UNION ALL 连接两个查询结果。
SELECT ename FROM t_emp WHERE deptno = 20
UNION ALL
SELECT ename FROM t_emp WHERE deptno = 30;
7. 尽量少用 in 和 not in 运算符,原因和 or 运算符一样,都属于逻辑或关系
SELECT ename FROM t_emp WHERE deptno IN (20,30);
也是使用 UNION ALL 进行优化
SELECT ename FROM t_emp WHERE deptno = 20
UNION ALL
SELECT ename FROM t_emp WHERE deptno = 30;
8. 避免条件语句中的数据类型转换
SELECT ename FROM t_emp WHERE deptno = '20';
如果 deptno 字段是整数类型,但是却去跟字符串20进行比较,数据库需要先转换数据类型然后才能进行比较,所以这样会影响数据库的执行速度。
9. 在表达式左侧使用运算符和函数都会让索引失效
SELECT ename FROM t_emp WHERE sal * 12 >= 100000;
比如查询年薪大于10万的用户,将乘以12写在表达式左侧是错误的
SELECT ename FROM t_emp WHERE sal >= 100000 / 12;
正确写法应该是写在右侧,这样是可以利用索引的。
下面的sql语句,如果hiredate字段设置了索引,使用YEAR(hiredate)函数是无法使用索引的。
SELECT ename FROM t_emp WHERE YEAR ( hiredate ) >= 2000;
改成这样即可
SELECT ename FROM t_emp WHERE hiredate >= '2000-01-01 00:00:00';