正文
char
中还会自动补齐空格,因为你
insert
到一个
char
字段自动补充了空格的,但是
select
后空格没有删除,因此
char
类型查询的时候一定要记得使用
trim
,这是写本文章的原因。
如果开发人员细化使用
rpad()
技巧将绑定变量转换为某种能与
char
字段相比较的类型(当然,与截断
trim
数据库列相比,填充绑定变量的做法更好一些,因为对列应用函数
trim
很容易导致无法使用该列上现有的索引),可能必须考虑到经过一段时间后列长度的变化。如果字段的大小有变化,应用就会受到影响,因为它必须修改字段宽度。
正是因为以上原因,定宽的存储空间可能导致表和相关索引比平常大出许多,还伴随着绑定变量问题,所以无论什么场合都要避免使用char类型。
六、where中使用默认值代替null
1、反例
SELECT * FROM user WHERE age IS NOT NULL
2、正例
SELECT * FROM user WHERE age>0
3、理由
-
并不是说使用了
is null
或者
is not null
就会不走索引了,这个跟
mysql
版本以及查询成本都有关;
-
如果
mysql
优化器发现,走索引比不走索引成本还要高,就会放弃索引,这些条件
!=,<>,is null,is not null
经常被认为让索引失效;
-
其实是因为一般情况下,查询的成本高,优化器自动放弃索引的;
-
如果把
null
值,换成默认值,很多时候让走索引成为可能,同时,表达意思也相对清晰一点;
七、避免在where子句中使用!=或<>操作符
1、反例
SELECT * FROM user WHERE salary!=5000
SELECT * FROM user WHERE salary<>5000
2、理由
-
-
应尽量避免在
where
子句中使用
!=
或
<>
操作符,否则引擎将放弃使用索引而进行全表扫描
-
实现业务优先,实在没办法,就只能使用,并不是不能使用
八、inner join 、left join、right join,优先使用inner join
三种连接如果结果相同,优先使用inner join,如果使用left join左边表尽量小。
-
inner join 内连接,只保留两张表中完全匹配的结果集;
-
left join会返回左表所有的行,即使在右表中没有匹配的记录;
-
right join会返回右表所有的行,即使在左表中没有匹配的记录;
为什么?
-
如果inner join是等值连接,返回的行数比较少,所以性能相对会好一点;
-
使用了左连接,左边表数据结果尽量小,条件尽量放到左边处理,意味着返回的行数可能比较少;
-
这是mysql优化原则,就是小表驱动大表,小的数据集驱动大的数据集,从而让性能更优;
九、提高group by语句的效率
1、反例
先分组,再过滤
select job, avg(salary) from employee
group by job
having job ='develop' or job = 'test';
2、正例
先过滤,后分组
select job,avg(salary) from employee
where job ='develop' or job = 'test'
group by job;
3、理由
可以在执行到该语句前,把不需要的记录过滤掉
十、清空表时优先使用truncate
truncate table
在功能上与不带
where
子句的
delete
语句相同:二者均删除表中的全部行。但
truncate table
比
delete
速度快,且使用的系统和事务日志资源少。
delete
语句每次删除一行,并在事务日志中为所删除的每行记录一项。
truncate table
通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。
truncate table
删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。如果要删除表定义及其数据,请使用
drop table
语句。
对于由
foreign key
约束引用的表,不能使用
truncate table
,而应使用不带
where
子句的 DELETE 语句。由于
truncate table
不记录在日志中,所以它不能激活触发器。