【问题标题】:Suggestion on Database structure for relational data关于关系数据的数据库结构的建议
【发布时间】:2010-04-19 13:50:37
【问题描述】:

我一直在努力解决这个问题很长一段时间,并且带有“慢查询”警告的自动邮件仍然弹出。基本上,我有一个带有相应表的博客以及一个跟踪如何跟踪的表每个博客都被浏览了很多次。最后一张表有大量记录,因为该页面的流量相对较高,并且它将每次点击记录为单独的行。我已经尝试在 WHERE 子句中包含的字段上使用索引,但它似乎没有帮助。我还尝试每周通过删除旧(> 1.weeks)记录来清理表格。所以,我问你们,你们会怎么解决这个问题?

我知道导致运行缓慢的查询是由 Rails 生成的,如下所示:

SELECT count(*) AS count_all
FROM blog_views
WHERE (created_at >= '2010-01-01 00:00:01' AND blog_id = 1);

这些表具有以下结构:

CREATE TABLE IF NOT EXISTS 'blogs' (
  'id' int(11) NOT NULL auto_increment,
  'name' varchar(255) default NULL,
  'perma_name' varchar(255) default NULL,
  'author_id' int(11) default NULL,
  'created_at' datetime default NULL,
  'updated_at' datetime default NULL,`
  'blog_picture_id' int(11) default NULL,
  'blog_picture2_id' int(11) default NULL,
  'page_id' int(11) default NULL,
  'blog_picture3_id' int(11) default NULL,
  'active' tinyint(1) default '1',
  PRIMARY KEY  ('id'),
  KEY 'index_blogs_on_author_id' ('author_id')
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS 'blog_views' (
  'id' int(11) NOT NULL auto_increment,
  'blog_id' int(11) default NULL,
  'ip' varchar(255) default NULL,
  'created_at' datetime default NULL,
  'updated_at' datetime default NULL,
  PRIMARY KEY  ('id'),
  KEY 'index_blog_views_on_blog_id' ('blog_id'),
  KEY 'created_at' ('created_at')
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

【问题讨论】:

    标签: mysql ruby-on-rails performance


    【解决方案1】:

    很可能,您需要在 both 列 blog_id 和 created_at 上一个索引

    不是两个索引,每个索引都有一列...

    ...
    KEY 'whizzy' ('blog_id', 'created_at'),
    ...
    

    CREATE TABLE 你可以有复合索引/键:

    ...
    {INDEX|KEY} [index_name] [index_type] (index_col_name,...)
    ...
    

    如果这不起作用,还可以尝试颠倒顺序

    【讨论】:

    • 我很想看看这个建议是否可行。我个人不明白为什么组合索引而不是单独索引会产生重大影响。
    • @ercan:优化器必须查询 2 个索引并合并结果,或者不使用任何一个索引。搜索在 2 列上,因此将索引放在 2 列上。适用于所有主要数据库引擎。 AKA,每个当前索引本身都不够好......
    • 我即将实现这个,看看它是否有帮助。只需要一种在场景前后进行基准测试的好方法,猜测在 Rails 中进行测试就可以了。我很快就会返回结果。
    • 有什么简单的方法可以在 phpMyAdmin 中进行检查吗?
    【解决方案2】:

    我不会将每个点击记录为唯一的行......

    如果您只想计算博客被查看的次数,为什么不为每个博客创建一行,并将 view_count 字段添加到您的表中。 那么只有这个字段正在更新....

    如果您需要跟踪用户/ips,并且您想知道每个用户点击博客的次数,请以类似于此的结构创建一个额外的表:

    id (pk)

    blog_id

    user_id / ip_address

    日期

    hit_counts

    通过这样的结构,您可以大致了解博客的浏览次数,还可以了解有多少用户以及每个用户点击了多少次...

    或者,如果您真的想为每次点击创建行,并且索引没有足够快的过程,您可能会考虑更强大的服务器,或者不同的数据库管理系统....

    希望这会有所帮助!

    【讨论】:

      【解决方案3】:

      我的想法和皮耶罗一样,但有些不同。

      您可以在名为“hits”的博客表中添加一列,并在发生点击时始终增加该字段的值,并像现在一样在 blog_view 表中插入新记录。

      通过这样做,您无需运行查询来计算命中数,您还可以在需要时查看命中详细信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-22
        • 2011-08-25
        • 1970-01-01
        • 2017-09-01
        • 2014-07-22
        • 2012-07-10
        • 2014-09-26
        相关资源
        最近更新 更多