优化数据库和前端的交互
# 优化数据库和前端的交互
如何根据数据库的性质进行资源优化?
此文件使用Typora编辑 Typora 旧版本 (opens new window)
应避免在前端中进行大量的数据库查询
数据库访问框架一般都提供了批量提交的接口,批量提交减少了客户端和服务端的交互次数,从而减少了多次发起的网络延时靠小,也降低了数据库的CPU开销,但不会太减少数据库的物理IO
磁盘读取靠的是机械运动,内存指令依靠的是电信号,执行一次IO的时间可以执行百万级数量的指令,因此减少数据库的IO操作是优化的一种。
前两周做了查询的优化
pgsql里查询默认是使用Nested Loop
分为内外表,每扫描一次外表都需要在内标查找匹配的行,是一个嵌套循环。时间复杂度是O(N*M) ,加索引后没有很明显的加快。对大数据集的连接很不友好
改用hash-join能够将两个表中较小的表作为hash表,取扫描另一个表的数据,根据连接条件获取。hash表是存在内存中的,基本上只需要将大小表扫描一遍就可以得出最终的结果集。
pgsql中hash-join的开启方法是
String sqlset = "SET enable_nestloop = off; " + // 禁用嵌套循环,强制使用Hash Join
"SET work_mem = '64MB'; "; // 确保哈希表有足够内存
//需要执行的sql语句
String sqlseee = "SET enable_nestloop = on; " + // 恢复默认配置
"SET work_mem = default;";
2
3
4
5
6
7
数据库多表连接方式介绍-HASH-JOIN - _雨 - 博客园 (cnblogs.com) (opens new window)
磁盘读取数据靠的是机械运动,每次读取数据的事件可以分为寻道时间、旋转延迟、传输时间三个部分。寻道时间指的是磁臂移动到指定磁道所需要的时间,主流磁盘一般在5ms以下。旋转延迟就是我们经常听说的磁盘转速,比如一个磁盘7200转,表示每分钟能转7200次,也就是说1秒钟能转120次。每转一圈的时间就是1÷7200601000=8.3333ms
平均旋转延迟时间8.33÷2=4.17ms(平均情况下,需要旋转半圈)
传输时间一般在零点几毫秒,相对于前两个时可以忽略不计
那么访问一次磁盘的事件,即一次磁盘IO(磁盘读取和写入)的事件等于5+4.17=9ms左右,听起来还挺不错的,但要知道一台500-MIPS的机器每秒可以执行5亿条指令,因为指令依靠的是电的性质。换句话说,执行一次IO的事件可以执行450万条指令,数据库数量动辄几百万至上千万,会影响到指令的执行。
Spring事务管理
在方法加上 @Transactional 注解
加上@Transactional 注解的方法在抛出异常后,事务会自动回滚,不会执行
Spring 本身是没有事务的,只有数据库才会有事务
将一系列数据库操作作为一个原子单元执行,要么全部成功,要么全部回滚。
# 数据回滚的含义 (opens new window)
数据回滚是指在数据库操作过程中,当发生错误或异常时,将数据库恢复到操作之前的状态。它是一种确保数据一致性和完整性的机制,常用于事务管理中。
回滚 rollback是在提交之前撤销所有操作
撤销undo是在提交之后撤销已经对数据库做出的修改