我正在考虑通过添加一个由许多(〜8)个规范化表提供的非规范化表来在数据库中添加一些非规范化信息,特别是为了改善我网站上核心用例的选择查询时间。
当前的查询方法存在的问题是:
查询时间很慢,有8到12个联接(一些左联接)可以访问此用例的信息,某些查询可能需要3000毫秒。
表锁定/阻止,当信息在一天或一周的繁忙时间更新时(由于我使用的是MyIsam表),查询将被锁定/阻止,这可能会导致进一步的问题(连接用尽,性能降低)
我正在使用Hibernate(3.5.2),Mysql 5.0(所有MyIsam表)和Java 1.6
我想提出一些具体的建议(最好是基于具体经验),确切地讲,这是更新非规范化表的最佳方法。
我想到以下内容
创建具有InnoDb类型的非规范化表,以便获得行级锁定而不是表锁定
在正确规范化的表上创建触发器,以更新非规范化表,
我在找:
陷阱-我可能没有想到的事情会影响我想要的结果。
特定的MySql设置可以提高性能,减少对非规范化表的锁定/阻塞。
针对这种情况编写触发器的最佳方法。
?
让我知道是否需要其他信息来帮助回答这个问题。
干杯。
最佳答案
我现在已经实现了这一点,所以我想分享一下自己的工作,我问了一位dba(Greg)的伴侣以获取一些提示,他的回答基本上推动了我的实现:
无论如何,暗示使用TRIGGERS的“ Catcall”(至少在我的情况下)可能不是最佳解决方案。 Greg建议创建两个具有相同架构的非规范化表,然后创建一个VIEW,以在两个非规范化表之间交替,一个处于“活动”状态,另一个处于“非活动”状态,活动表将是我的网站正在主动查询的表应用程序和非活动表可以使用非规范化信息进行更新。
我的应用程序将对名称保持不变的VIEW运行查询。
这就是症结所在。
一些实现细节(mysql 5.0.n):
我使用存储过程来更新信息,然后将View从denorm_table_a切换到denorm_table_b。
需要更新我的数据库用户的权限
*在dbname上授予创建,创建视图,执行,创建例程,更改例程,拖放,插入,删除,更新,更改,选择,索引的功能。* TO'dbuser'@'%';
要创建表的副本,请执行以下操作:CREATE TABLE ... LIKE ....;该命令真的很有用(它也会复制索引定义)
创建视图很简单
创建或替换视图denorm_table AS SELECT * FROM denorm_table_a;
创建或替换视图denorm_table AS SELECT * FROM denorm_table_b;
我在中间层创建了一个特殊的“非规范化查询”对象,然后将该对象(通过休眠)映射到非规范化表(或实际上是View),并允许通过Hibernate Criteria机制轻松而灵活地进行查询。
无论如何,如果有人需要更多详细信息,希望对您有所帮助,请告诉我,
干杯
西蒙