Java 实体及;实体属性。有效搜索的数据库设计
过去两天,我一直在为下面描述的问题寻找合适的解决方案 在我的独立通知服务模块中,我有一个抽象消息实体。消息具有“to”、“from”、“sentAt”、“receivedAt”和其他属性。通知服务的职责是:Java 实体及;实体属性。有效搜索的数据库设计,java,sql,postgresql,database-design,database-performance,Java,Sql,Postgresql,Database Design,Database Performance,过去两天,我一直在为下面描述的问题寻找合适的解决方案 在我的独立通知服务模块中,我有一个抽象消息实体。消息具有“to”、“from”、“sentAt”、“receivedAt”和其他属性。通知服务的职责是: 使用不同的注册消息提供商(SMS、电子邮件、Skype等)发送新消息 从注册的消息提供程序接收新消息 更新已发送邮件的状态 通知服务模块作为独立模块开发,可通过SOAP协议使用。许多客户端可以使用此模块发送或搜索已接收的消息 客户端希望在发送消息时附加一些属性(~smth-like标记),以
SELECT * FROM (SELECT message_id FROM custom_message_properties
WHERE CONCAT(CONCAT(key, ':'), value) IN ('property1:value1', 'property2:value2')
GROUP BY message_id having(count(*)) = 2)
as cmp JOIN message m ON cmp.message_id = m.id ORDER BY ID LIMIT 100 OFFSET 0
在具有小数据的数据库中,查询工作得很好(尽管我觉得不是很好)。我决定检查结果,看是否有真正等待的数据。
所以我生成了10000条消息,其中包含400000个自定义属性和检查结果。执行时间约为2分钟。最耗时的操作是以下子选择:
SELECT message_id FROM custom_message_properties
WHERE CONCAT(CONCAT(key, ':'), value) IN ('property1:value1', 'property2:value2')
我知道字符串比较非常慢,因为没有使用数据库索引功能。我决定改变数据库结构,将“key”和“value”列合并为一个列。因此,我通过数据库方案进行了更新:
我再次检查了结果。现在执行时间约为20秒。它好得多,但仍然不适合生产使用
因此,现在我不知道如何在应用程序架构设计没有重大变化的情况下提高性能。
我唯一的想法就是为每个客户机创建一个单独的表,其中包含所需的客户机属性
client(i)_custom_properties {
mid bigint, // foreign key references message (id)
p1 type1,
p2 type2,
......
pn type(n)
}
我花了很多时间试图找到有用的信息。我还分析了“stackoverflow”数据库,因为我觉得它应该是完全相同的。但是在“stackoverflow”中有大约50000个不同的标签。我的数据库可能没有这么多
感谢您的帮助。提前谢谢
我使用的项目环境:
除了为每个客户端创建包含客户端属性的附加表之外,我还没有找到任何合适的解决方案。 我知道,这个解决方案没有那么灵活, 但现在搜索查询时间不到1秒
将来,我将尝试使用noSQL数据存储解决同样的问题 非常感谢您的反馈。我分析了这篇文章。对于我的项目,很难使用非jpa的东西,比如postgres数组和jsonb数据类型。稍后我想构建projectenv。在noSQL数据存储(如elastic search或mongodb)上,测试相同的查询。欢迎来到ORM模糊化关系模型的奇妙世界,您不需要noSQL解决方案。你只需要去掉你的模糊层,它阻止你在Postgres中使用noSQL特性。