java - 如何有效地为很多重复的表保存值(value)?

标签 java database oracle performance java.util.concurrent

我有一个名为 Message 的实体,其中包含以下字段:id (PK)、String messageXML 和 Timestamp date。和将对象存储到 Oracle 数据库 (11g)/MyBatis 中的简单 dao

代码看起来像这样:

服务:

void process throws ProcessException {
Message message = wrapper.getMessage(request);
Long messageId;
try {
messageId = (Long) dao.save(message);
} catch (DaoException e) {
throw ProcessException(e);
}

private String mapperName = "messageMapper";

Serializable save(Message message) throws DaoException {
try {
     getSqlSession().insert(mapperName + ".insert", message); 
return message.getPrimaryKey();
} catch (Exception e) {
throw DaoException(e);
}

简单的代码。不幸的是,此方法 process(req) 的负载约为 500 req/sec。有时我会在保存消息时锁定数据库。

为了解决这个问题,我想到了乘法表消息,例如我将有五个表消息 1、消息 2 ... 消息 5,在保存实体消息期间我将绘制(如循环算法)表 - 例如:

private Random generator; 

public MessageDao() {
this.generator = new Random();

Serializable save(Message message) throws DaoException {
try {
     getSqlSession().insert(getMapperName() + ".insert", message); 
return message.getPrimaryKey();
} catch (Exception e) {
throw DaoException(e);
}

private String getMapperName() {
return this.mapperName.concat(String.valueOf(generator.nextInt(5))); //could be more effeciency of course
}

您对这个解决方案有何看法?能有效率吗?我怎样才能做得更好?瓶颈在哪里?

最佳答案

从字里行间来看,我猜您有许多代码实例正在运行以服务于多个并发请求,因此您会引起争用。或者您有 1 台服务器每秒发出 500 个请求并且您遇到等待。不起诉你的意思。在前一种情况下,您可能需要查看盘区分配——如果表/索引的下一个盘区大小很小,您会在 Oracle 获取下一个盘区时定期看到延迟。尺寸太小,你会经常遇到这种延迟,尺寸大,当它最终用完时,等待时间会更长。您可以做一些事情,比如每周计算存储量,并有一个每周程序相应地“增长”表/索引,以避免在操作时间内发生这种情况。我很想检查统计数据并查看等待时间。

但是,如果原因是并发(可能除了范围管理之外),那么您可能在用于强制执行 PK 约束的索引上发生热 block 争用。缓解这种情况的典型策略包括 REVERSE 索引(无需更改代码),或者更有争议的是通过添加一个简单的列来使用具有较弱唯一约束的分区来进一步隔离并发 session 。例如。将列 serverId 添加到表中,并按此列和现有 PK 列进行分区。为每个应用程序服务器分配一个唯一的 serverId(配置/启动文件)。修改插入以包括 serverID。每个服务器有 1 个分区。有争议,因为约束较弱(具体到分区的工作方式),这将是纯粹主义者的诅咒,但这是我在 Oracle 咨询项目中使用的东西,以最大限度地提高 Exadata 的性能。所以,它就在那里。当然,分区可以被认为是不同的表组合成一个 super 表,所以你写到单独的表的想法与这里的建议相去甚远。分区的优势在于它是一种更自然的数据分组机制,添加新分区比扩展时添加新表所需的工作更少。

关于java - 如何有效地为很多重复的表保存值(value)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26176139/

相关文章:

Java - 将字符串转换为有效的 URI 对象

java - 如何替换 .m2 存储库中的 Jar

database - 按相似列名对查询结果进行分组

sql - oracle sql developer tool - 提交后数据不可用

sql - 使用循环 Oracle 为每个 ID 遍历的完整路径

oracle - 如何从oracle pl/sql中的数据库中提取所有表的表属性,如列名、数据类型、可为空

java - JSON 文档 POJO 中的示例数据

java - Hibernate工具——生成实体JPA

database - 按特定字段获取对象

jquery - executeSql 查询错误