作为一名后端程序员,能够说天天都要跟数据库打交道,不论应用的是 MySQL,Oracle 还是 SQL Server,毫无疑问都逃不开 SQL,所以日常工作中对于 SQL 的性能优化堪称说非常重要。明天阿粉就带大家看一下,每个后端程序员都应该晓得的十个晋升查问性能的技巧。
1、应用 Exists 代替子查问
子查问在日常的工作中不可避免肯定会应用到,很多时候咱们的用法都是这样的:
SELECT Id, Name
FROM Employee
WHERE DeptId In (SELECT Id
FROM Department
WHERE Name like ‘%Management%’);
置信大家平时必定都是这样来应用的,其实还有一种更好的办法,如下所示:
SELECT Id, Name
FROM Employee
WHERE DeptId Exist (SELECT Id
FROM Department
WHERE Name like ‘%Management%’);
这里咱们应用 exist 关键字而不是 In 关键字,当然如果在数据量不大的时候,两种形式都能够,然而当数据量很大的时候,exist 的形式会比 in 的形式效率高很多。因为 Exist 函数依据查问后果返回一个布尔值,速度会快很多。
2、适当的应用 JOIN 来代替子查问
除了下面的 exist 之外在有些场景咱们能够应用 JOIN 来替换子查问,毕竟子查问的成果是很差的,如下所示:
SELECT Id, Name
FROM Employee
WHERE DeptId in (SELECT Id
FROM Department
WHERE Name like ‘%Management%’);
应用 JOIN 的形式如下:
SELECT Emp.Id, Emp.Name,Dept.DeptName
FROM Employee Emp
RIGHT JOIN Department Dept on Emp.DeptId = Dept.Id WHERE Dept.DeptName like ‘%Management%’;
3、应用 Where 代替不必要的 Having
对于 where 的应用置信大家都很善于,然而对于 Having 的应用可能平时用得不多,阿粉这里只能说:用得不多,挺好的!对于 Having 咱们是能不必就不必不到万不得已的时候不要用,说真的阿粉工作这么多年,真没有应用 Having 的场景。咱们先看上面的示例:
Having 的用法
SELECT Emp.Id, Emp.Name,Dept.DeptName,Emp.Salary
FROM Employee Emp
RIGHT JOIN Department Dept on Emp.DeptId = Dept.Id
GROUP BY dept.DeptName
HAVING Emp.Salary >= 20000;
Where 的用法
SELECT Emp.Id, Emp.Name,Dept.DeptName,Emp.Salary
FROM Employee Emp
RIGHT JOIN Department Dept on Emp.DeptId = Dept.Id
WHERE Emp.Salary >= 20000;
为什么说 Having 的性能没有 Where 高呢?那是因为 Where 是一种准确的匹配,然而 Having 是须要配合 Group By 来配合应用,只有波及到 Group By 天然就效率高不起来了。
4、应用准确的字段类型
有些小伙伴为了零碎的可扩展性或者压根就不晓得该把数据库字段的类型设置什么,所以就全副应用 char 或者 varchar,总感觉这样更灵便,然而往往这个时候是对系统的最大隐患。
在应用工夫类型的字段的时候,就须要设置成 DateTime,不能用 varchar;在应用标识是否删除的时候就应该应用 tinyint,能用 varchar 的就不要用 char;对于大字段 text 须要独立进去,这样在查问的时候就不会影响性能;对于能设置成惟一键的就须要设置成惟一键,因为你永远无奈防止程序会呈现脏数据,要在数据层保障一致性。
5、应用批处理代替循环
在插入数据的时候的,咱们能够应用 values 来批量进行插入,而不是通过循环来进行单条数据的查问,如下所示:
// 不可取
For(Int i = 0;i <= 5; i++)
{
INSER INTO Table1(Id,Value) Values(i , ‘Value’ + i);
}
// 举荐
INSERT INTO Table1(Id, Value)
Values(1,Value1),(2,Value2),(2,Value3),(4,Value4),(5,Value5);
不过要留神 values 前面的数量也是有限度的,所以两者能够联合应用,具体的能够依据表字段的多少来决定分多少批来执行。另外这里有一个留神的点,很多零碎都会底层做操作日志,而且很多时候可能是 SQL 级别的,那这个时候就须要留神,记录操作日志的表的字段是有长度限度的,这里整个 SQL 的长度是不能超过日志字段的长度的。
6、应用 UNION ALL 代替 UNION
在应用联结查问的时候,很多时候咱们会应用到 UNION ALL 或者 UNION 来联结多个表,进行汇总。那么 UNION ALL 和 UNION 的区别是什么呢?这两个的区别是 UNION ALL 会返回联结后的所有行记录,而 UNION 是会进行去重后返回。
比如说咱们有两张表 teacher 和 student,外面的数据别离是上面
8 个晋升 SQL 性能的 Tips,每个后端都应该晓得
8 个晋升 SQL 性能的 Tips,每个后端都应该晓得
这里这两张表当中,存在雷同的一条数据,就是(4,马六)这一条数据,咱们能够看看应用 UNION ALL 和 UNION 的成果
8 个晋升 SQL 性能的 Tips,每个后端都应该晓得
8 个晋升 SQL 性能的 Tips,每个后端都应该晓得
能够看到第二次的查问后果中曾经少了一行,阐明咱们下面说的 UNION 会去重的逻辑是存在的,而且去重是全字段都雷同的时候才会被去重。
7、用准确的字段代替 *
另一个比拟影响性能的点是应用 ,很多小伙伴为了省事,在编写查问语句的时候,会应用 来代替所有的字段,其实并不是说这种写法有什么问题,只是这种写法有点不可控,应用 示意要查问所有字段,当咱们的表是一个很简略的表,而且外面的字段都是一些小字段的时候,应用 齐全是能够的。
然而如果是对于一些大表特地是有 text 这种大字段的表,或者是一些敏感数据的表,咱们还应用 * 号去查问数据的话,就会有很大的问题了,一方面是有安全隐患,一方面还是减少磁盘,内存和网络的传输,齐全得失相当。
8、给必要的字段减少索引
索引作为数据库外面一个很重要的内容,相比大家都不生疏,给必要的字段加上索引也是很有必要的,除了主键索引,咱们还能够增加聚簇索引和惟一索引,对于索引的内容感兴趣的能够去看看咱们的这篇文章面试官问我索引为什么这快?我如同解释不分明了,这里阿粉就不细说了。
总结
后端程序员除了跟服务器打交道之外最多的就是跟数据库打交道了,如何在数据库层面提效也是一个短暂的话题,这也是为什么数据库能失去倒退的起因,从关系型数据库到 NoSQL 数据库,从 MySQL 到 ClickHouse,数据库行业也在短暂的倒退。