我有一个大型的标准化订单数据数据库,查询报表的速度变得非常慢。我在报表中使用的许多查询联接了五个或六个表,并且不得不检查成千上万的行。
查询很多,并且已经对大多数查询进行了优化,以减少服务器负载并提高速度。我认为是时候开始以非规范化格式保留数据副本了。
关于方法有什么想法吗?我应该从几个最糟糕的查询开始,然后再去那里吗?
问题来源于stack overflow
我对有关mysql的mssql的了解更多,但我认为所讨论的联接数或行数不会导致使用正确索引的太多问题。您是否分析了查询计划以查看是否缺少任何计划?
http://dev.mysql.com/doc/refman/5.0/en/explain.html
话虽如此,一旦您对索引感到满意并用尽了所有其他途径,反规范化可能是正确的答案。如果仅存在一个或两个问题,则手动方法可能是合适的,而某种数据仓库工具可能更适合创建用于开发数据多维数据集的平台。
我发现这是一个涉及该主题的网站:
http://www.meansandends.com/mysql-data-warehouse/?link_body%2Fbody=%7Bincl%3AAggregation%7D
这是一种简单的技术,如果您一次只执行几个操作(并且我不是要替换OLTP表,而只是创建一个用于报告目的的新表),则可以使用它使非规范化查询保持简单。假设您在应用程序中有以下查询:
select a.name, b.address from tbla a join tblb b on b.fk_a_id = a.id where a.id=1 您可以创建一个非规范化表并使用几乎相同的查询进行填充:
create table tbl_ab (a_id, a_name, b_address); -- (types elided) 注意下划线与您使用的表别名匹配
insert tbl_ab select a.id, a.name, b.address from tbla a join tblb b on b.fk_a_id = a.id -- no where clause because you want everything 然后,要修复您的应用以使用新的非规范化表格,请在下划线处切换点。
select a_name as name, b_address as address from tbl_ab where a_id = 1; 对于庞大的查询,这可以节省大量时间,并清楚说明数据的来源,并且您可以重复使用已有的查询。
记住,我只是提倡将此作为最后的手段。我敢打赌,有一些索引可以为您提供帮助。而且,当您进行非规范化时,请不要忘记考虑磁盘上的额外空间,并弄清楚何时运行查询来填充新表。这可能应该在晚上或活动量少的时候。而且,该表中的数据当然永远不会是最新的。
[另一个编辑]不要忘记,您创建的新表也需要建立索引!好处是您可以索引自己的内容,而不必担心更新锁争用,因为除了批量插入之外,该表仅会显示选择内容。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。