专栏名称: 数据分析与开发
伯乐在线旗下账号,分享数据库相关技术文章、教程和工具,另外还包括数据库相关的工作。偶尔也谈谈程序员人生 :)
目录
相关文章推荐
数据中心运维管理  ·  突发!又一储能电站发生火灾 ·  3 天前  
数据中心运维管理  ·  别错过!配电间、配电室等防火措施,一篇全搞定 ·  2 天前  
数据中心运维管理  ·  如何为布线环境选择合适的网络电缆标签 ·  昨天  
AustinDatabases  ·  MongoDB ... ·  昨天  
51好读  ›  专栏  ›  数据分析与开发

SQL 优化 20 连问

数据分析与开发  · 公众号  · 数据库  · 2023-04-27 12:10

正文

请到「今天看啥」查看全文


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、理由

  1. 并不是说使用了 is null 或者 is not null 就会不走索引了,这个跟 mysql 版本以及查询成本都有关;
  2. 如果 mysql 优化器发现,走索引比不走索引成本还要高,就会放弃索引,这些条件 !=,<>,is null,is not null 经常被认为让索引失效;
  3. 其实是因为一般情况下,查询的成本高,优化器自动放弃索引的;
  4. 如果把 null 值,换成默认值,很多时候让走索引成为可能,同时,表达意思也相对清晰一点;

七、避免在where子句中使用!=或<>操作符

1、反例

SELECT * FROM user WHERE salary!=5000

SELECT * FROM user WHERE salary<>5000

2、理由

  1. 使用 != <> 很可能会让索引失效
  2. 应尽量避免在 where 子句中使用 != <> 操作符,否则引擎将放弃使用索引而进行全表扫描
  3. 实现业务优先,实在没办法,就只能使用,并不是不能使用

八、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 不记录在日志中,所以它不能激活触发器。







请到「今天看啥」查看全文