我正在设计一个带有SQL后端的应用程序(Postgresql),我有一些设计问题。简而言之,数据库将用于存储动态发生的网络事件,因此插入速度和性能至关重要,因为“实时”操作取决于这些事件。数据在几个表中被转储为快速的默认格式,我目前正在使用postgresql触发器将这些数据放入用于报告的其他表中。
在典型事件中,数据被插入到两个不同的表中,每个表共享相同的主键(事件ID)。然后,我需要将数据移动并重新排列到基于Web的报告界面使用的某些不同的表中。我的主要目标/关注点是将负载从初始插入表中移除,以便他们可以完成他们的工作。报告是次要的,但通过触发器实现这一点仍然很好,而不是我必须查询和管理已经处理的事件的cron作业。报告应该/将永远不会触及初始插入表。表现明智......这是有意义还是我完全离开了?
一旦数据出现在相应的报告表中,我就不需要太长时间地依赖插入表中的数据了,所以我会保留那些经常修剪插入性能的数据。在考虑这种情况时,我肯定是半常见的,我提出了三种选择:
使用触发器在初始行插入时触发并填充报告表。这是我最初的计划。
使用触发器将插入数据复制到临时表(格式相同),然后触发或cron填充报告表。这只是一个想法,但我认为对临时表的简单复制操作将卸载上述解决方案中任何触发器的查询。
修改我的初始输出程序以将所有数据转储到单个表(vs两个表),然后触发该插入以填充报告表。因此,在解决方案1是多表到多表触发器情况的情况下,这将是单表源到多表触发器。
我在想这个吗?我想说得对。任何意见都非常感谢!
答案 0 :(得分:2)
您可能会遇到性能略有提升,因为有更多“事情”要做(尽管它们不应以任何方式影响操作)。但是使用触发器/其他PL是一种很好的方法,可以将它减少到最小的子程序,它们的执行速度比从应用程序发送到DB-Server的代码要快。
我会接受你的第一个想法1)
,因为在我看来,这是最干净,最有效的方式。
2)
是性能最苛刻的解决方案,因为cron将比使用服务器端功能的其他解决方案执行更多查询。 3)
是可能的,但会导致“丑陋的”数据库布局。
答案 1 :(得分:0)
这是一个旧的,但在这里添加我的答案。
报告是次要的,但通过触发器实现这一点仍然很好,而不是我必须查询和管理已经处理的事件的cron作业。报告应该/将永远不会触及初始插入表。表现明智......这是有意义还是我完全离开了?
这可能很遥远,我担心,但在少数情况下可能不会。这取决于缓存对报告的影响。请记住,磁盘I / O和内存是你的商品,而且编写者和读者很少在PostgreSQL上相互阻塞(除非他们明确提升锁定 - 例如,SELECT ... FOR UPDATE将阻止编写者)。基本上,如果您的表格适合RAM,您最好不要向它们报告,因为您为事件条目的WAL段提交保留了磁盘I / O。如果它们不适合RAM,那么您可能会遇到由报告引起的缓存未命中问题。在这里实现您的视图(即制作触发器维护的表)可以减少这些,但它们具有显着的复杂性成本。这个,顺便说一下,如果你的选择1.所以我会把这个暂时作为过早优化。另外请记住,这可能会导致缓存未命中并锁定以这种方式实现视图的争用,因此您可能会以这种方式引发有关插入的性能问题。
请记住,如果您可以使用RAM进行操作(WAL提交除外),则不会出现性能问题。
#2。如果您将临时表称为CREATE TEMPORARY TABLE,那就是要求包含性能问题的混乱,并且报告没有显示您希望它们显示的内容。不要这样做。如果你这样做,你可能会:
等.....
简而言之,我认为你是在思考它。你可以通过在你的Pg盒子上碰撞RAM并确保你有足够的内核来处理适当数量的插入会话和报告会话。如果你的硬件计划正确,这一切都不应该是一个问题。