【问题标题】:Splitting up data in MySQL to make it faster and more accessible在 MySQL 中拆分数据以使其更快、更易于访问
【发布时间】:2017-11-01 12:29:03
【问题描述】:

我有一个非常大的 MySQL 数据库。因此,我能感觉到网站变慢了。

现在,在很多页面上,我只需要数据的一部分。例如,出于历史目的,我每 5 分钟存储一次有关用户的信息。但是在一页上我只需要最新的信息(而不是整个数据历史)。我在查询中通过一个简单的MAX(date) 来实现这一点。

现在我想知道是否最好创建一个单独的表来存储最新数据,这样查询就不必在数百万行之间搜索来自特定用户的最新数据,而是只是有一个表,里面只有每个用户的最新数据。

  • 这里的缺点是我必须每 5 分钟运行 2 次查询以在我的数据库中插入最新的历史记录,即在历史记录表中插入新数据并更新最新历史记录表中的数据。

  • 优点是 MySQL 需要处理的数据要少得多。

处理此类问题的常用方法是什么?

【问题讨论】:

  • 如果您显示当前的数据库结构(包括索引)可能会有所帮助;以及带有“simple MAX(date)”的查询。
  • 通常这个问题是通过索引来解决的——在这种疯狂的架构选择之前可能想尝试一下

标签: php mysql sql mariadb


【解决方案1】:

有多种方法可以处理大型表中的慢查询。最基本的三种方式是:


1:使用indexesuse them correctly。在大桌子上avoid table scans 很重要;这几乎总是对单个查询造成的最大性能影响。

例如,如果您要查询如下内容:select max(active_date) from activity where user_id=?,则在活动表中为 user_id 列查询create an index。一个索引可以有多个列,一个表可以有多个索引。

CREATE INDEX idx_user ON activity (user_id)

2:使用摘要/“缓存”表。这就是你所建议的。在您的情况下,您可以将插入 trigger 应用于您的活动表,这将在插入新行时更新您的摘要表。这意味着您不需要您的代码来执行两个查询。例如:

CREATE TRIGGER update_summary 
AFTER INSERT ON activity 
FOR EACH ROW
UPDATE activity_summary SET last_active_date=new.active_date WHERE user_id=new.user_id

您可以更改它以检查用户是否已经存在一行,如果这是他们的第一个活动,则进行插入。或者,您可以在用户注册时在汇总表中插入一行……或其他任何内容。


3:查看查询!使用 MySQL 的 EXPLAIN 命令获取查询计划,以查看优化器对您的查询做了什么。使用它来确保优化器避免对大型表进行表扫描(并在必要时创建或强制索引)。

【讨论】:

  • 非常感谢。这真的很有帮助。现在在工作台中导入数据库并尝试一些事情!
  • 谢谢霍根。 @Merijndk 在您的特定情况下,我建议使用汇总表。我毫不怀疑向您的表添加索引将使您的查询立即返回,但在企业范围内,DBA 会感谢您将查询远离可能被您的查询锁定的大型活动表。如果您每 5 分钟记录一次单个用户,并且您有 10,000 个用户,那么在主表上已经有很多操作(每秒 3-4 次插入)。
  • @RobbieToyota 添加良好的索引并使用伪造键确实对我有很大帮助(从 8.9 秒查询到 0.6 秒)
  • 更多关于summary tables
猜你喜欢
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-12
  • 2021-04-01
相关资源
最近更新 更多