我有一个规范化订单数据的大型数据库,查询报告变得非常慢.我在报告中使用的许多查询都会连接五到六个表,并且必须检查数十或数十万行.
有很多查询,大多数都已尽可能优化,以减少服务器负载和提高速度.我认为是时候开始以非规范化格式保存数据副本了.
关于方法的任何想法?我应该从几个最糟糕的问题开始,然后从那里开始?
我更了解mssql那个mysql,但我不认为你所谈论的连接数或行数应该会导致你使用正确的索引出现太多问题.您是否分析了查询计划以查看是否遗漏了任何查询计划?
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;
对于大量查询,这可以节省大量时间并清楚地显示数据的来源,并且您可以重复使用已有的查询.
请记住,我只是提倡这作为最后的手段.我敢打赌,有一些索引可以帮到你.当您取消规范化时,不要忘记考虑磁盘上的额外空间,并找出何时运行查询以填充新表.这应该是在晚上,或者在活动不足时.当然,该表中的数据永远不会是最新的.
[还有另一个编辑]不要忘记你创建的新表也需要编入索引!好的部分是您可以索引内容的内容而不用担心更新锁争用,因为除了批量插入外,表只会看到选择.