【问题标题】:Slow query while using DISTINCT in MYSQL with various other conditions (10 million records)在具有各种其他条件的 MYSQL 中使用 DISTINCT 时查询缓慢(1000 万条记录)
【发布时间】:2018-11-13 02:05:47
【问题描述】:

我在一个社交网络上工作,像往常一样,有一个供用户使用的提要,他们可以看到用户正在关注的用户的活动,而不是被用户阻止的用户。

这是活动表中当前正在使用的查询

SELECT DISTINCT `activities`.`post_id` 
FROM `activities` 
WHERE (activities.user_id IN ([followed_user_ids]) AND 
activities.language_id IN ([language_ids]) AND 
activities.id <= ?) AND 
(`activities`.`post_user_id` NOT IN ([blocked_and_deactivated_user_ids])) 
ORDER BY `activities`.`id` DESC 
LIMIT 1 OFFSET 10

这是导致问题的查询。有时 Mysql CPU 使用率会达到 100%,这会给用户带来问题。我还在活动表中使用的列上使用了索引。

Activities 表中有 1000 万条记录。

我可以做哪些改变来优化它?

【问题讨论】:

  • 您是否尝试过调整您的 mysql 设置?你能发布你的my.cnf吗?你试过mysqltuner吗?您是否尝试查看 log_slow_queries 和 log-queries-not-using-indexes?
  • 你真的需要DISTINCT吗?
  • 您可以制作“临时”表来存储每个子集
  • @slowjack2k 我没有尝试调整 mysql 设置,它通常工作正常,但在较高的流量下查询会减慢很多,即大约 20 秒,然后冻结数据库。是因为我在这个查询中使用了 IN,并且由于 follow_user_ids 可以是 1000,这是值得关注的原因吗?
  • @Michael-sqlbot 我需要通过帖子找出不同的活动,这样用户就不会多次看到同一个帖子。

标签: mysql ruby ruby-on-rails-4 amazon-rds social-networking


【解决方案1】:

首先,对于 RDS 上的生产数据库,我建议创建一个 Read Replica,并将所有这些繁重的 SELECT 查询转移到副本。这是the link to the docs。 这样做可以缓解用户的冻结问题,因为繁重的查询不会在与通常工作负载相同的实例上执行。

其次,考虑为那些繁重的查询所涉及的表创建索引。要明智地选择要创建的索引,请使用 EXPLAIN 语句并检查主要瓶颈,即查询在哪里采取更多步骤来获取正确的数据。

如果你真的无法摆脱那些 IN 语句(我认为至少其中一些你应该能够,比如关注的用户 ID 和语言,也许你可以通过使用用户 ID 的简单连接来替换 IN)创建索引对于涉及的列。

告诉我们进展如何。

【讨论】:

    猜你喜欢
    • 2014-07-09
    • 2018-02-22
    • 2019-06-13
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多