代码之家  ›  专栏  ›  技术社区  ›  Eric Goodwin

什么是对mysql数据库进行非规范化的好方法?

  •  19
  • Eric Goodwin  · 技术社区  · 17 年前

    我有一个规范化订单数据的大型数据库,查询报告变得非常缓慢。我在报告中使用的许多查询连接五个或六个表,并且必须检查成千上万行。

    有什么办法吗?我是否应该从几个最糟糕的问题开始,然后从那里开始?

    8 回复  |  直到 12 年前
        1
  •  11
  •   Eric Z Beard    17 年前

    我比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

    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;
    

    对于大型查询,这可以节省大量时间并明确数据来自何处,并且您可以重复使用已有的查询。

    记住,我只是主张这是最后的手段。我打赌有一些索引可以帮助你。在反规范化时,不要忘记考虑磁盘上的额外空间,并确定何时运行查询以填充新表。这可能是在晚上,或者活动量少的时候。当然,表格中的数据永远不会是最新的。

        2
  •  2
  •   pix0r    17 年前

    MySQL5确实支持 views EXPLAIN 语法,以查看实际使用的索引以及减慢查询速度的原因。

    至于规范化数据(无论您是使用视图还是以更高效的方式复制数据),我认为从最慢的查询开始并逐步完成是一种很好的方法。

        3
  •  1
  •   Mike Stone    17 年前

    我知道这有点相切,但你有没有试过看看是否有更多的索引可以添加?

    我没有太多的数据库背景,但我最近经常使用数据库,我发现很多查询都可以通过添加索引来改进。

    我们正在使用DB2,有一个名为db2expln和db2advis的命令,第一个命令将指示是否正在使用表扫描和索引扫描,第二个命令将建议可以添加索引以提高性能。我相信MySQL也有类似的工具。。。

    无论如何,如果这是你还没有考虑过的事情,它对我帮助很大。。。但如果你已经走了这条路,那么我想这不是你想要的。

        4
  •  1
  •   Jarod Elliott    17 年前

    今年早些时候,我在MySQL数据库上发现了一件事,那就是复合索引的威力。例如,如果要报告日期范围内的订单号,则订单号和订单日期列上的复合索引可能会有所帮助。我相信MySQL只能使用一个索引进行查询,因此,如果您在订单号和订单日期上有单独的索引,则必须决定只使用其中一个索引。使用EXPLAIN命令可以帮助确定这一点。

    为了用好的索引(包括许多复合索引)来表示性能,我可以运行连接数据库中3个表的查询,在大多数情况下几乎可以立即得到结果。对于更复杂的报告,大多数查询在10秒内运行。这三个表分别有3300万行、1.1亿行和1.4亿行。请注意,我们已经对这些进行了稍微的标准化,以加快对数据库最常见的查询。

        5
  •  1
  •   Peter Stuifzand    17 年前

    对于MySQL,我喜欢这个演讲: Real World Web: Performance & Scalability, MySQL Edition . 这包含了很多不同的建议,可以提高MySQL的运行速度。

        6
  •  0
  •   Derek Park    17 年前

        7
  •  0
  •   Jarod Elliott    17 年前

    在我前面的回答之后,我们在某些情况下采取的另一种方法是将关键报告数据存储在单独的汇总表中。有些报告查询即使在非规范化和优化之后也会很慢,我们发现创建一个表并存储整个月的运行总计或摘要信息也会使月末报告更快。

    我们发现这种方法很容易实现,因为它没有破坏任何已经在工作的东西——它只是在某些点上插入额外的数据库。

        8
  •  0
  •   Eric Goodwin    17 年前