【问题标题】:What makes a query slow with very few rows in `EXPLAIN`?是什么让“EXPLAIN”中的行数很少的查询变慢?
【发布时间】:2015-09-30 10:38:26
【问题描述】:

我的查询跨越索引良好的JOIN 上的 4 个表,最多约 500 行。然而,查询通常需要几分钟才能完成。

我错过了什么?

EXPLAIN
SELECT
    homework.id AS homework_id,
    homework.description
FROM homework
JOIN student_homework_assn 
  ON homework.id = student_homework_assn.homework_id
JOIN class_student_assn 
  ON student_homework_assn.student_id = class_student_assn.student_id
JOIN class 
  ON class_student_assn.class_id = class.id
WHERE homework.grade IS NULL
  AND homework.homework_date > DATE_ADD(NOW(), INTERVAL -1 DAY)
  AND class.class_status_id = 2
LIMIT 1000;

*** row 1 ***
          table:  class
           type:  ref
  possible_keys:  PRIMARY,class_status_id,class_multi_1
            key:  class_status_id
        key_len:  4
            ref:  const
           rows:  539
          Extra:  Using index
*** row 2 ***
          table:  class_student_assn
           type:  ref
  possible_keys:  student_id_2,student_id
            key:  student_id_2
        key_len:  4
            ref:  class.id
           rows:  1
          Extra:  Using index
*** row 3 ***
          table:  student_homework_assn
           type:  ref
  possible_keys:  PRIMARY,idx_homework_id,idx_student_id
            key:  idx_student_id
        key_len:  8
            ref:  class_student_assn.student_id
           rows:  262
          Extra:  Using index
*** row 4 ***
          table:  homework
           type:  eq_ref
  possible_keys:  PRIMARY,id,homework_date
            key:  PRIMARY
        key_len:  8
            ref:  student_homework_assn.homework_id
           rows:  1
          Extra:  Using where

简要表说明:

Table                   # Rows
homework                200M
student_homework_assn    25M
class_student_assn        2k
class                     3k

接下来我应该在哪里查看以减少此查询的运行时间?

【问题讨论】:

  • BETWEEN DATE_ADD(NOW(), INTERVAL -1 DAY) AND DATE_ADD(NOW(), INTERVAL -0 DAY) => BETWEEN DATE_ADD(NOW(), INTERVAL -1 DAY) AND NOW()
  • 感谢@lad2025 的评论和编辑。我尝试了homework_date BETWEEN ... AND NOW()homework_date > DATE_ADD(NOW(), INTERVAL -1 DAY)。两个结果都一样长(200-300 秒!),并且与原始查询时间相似。下一步是什么?
  • 在这三个中,homework_date > DATE_ADD... 始终更快,但生产速度仍然慢(从不低于 90 秒)。

标签: mysql sql query-optimization


【解决方案1】:

您声明了索引良好的连接,但我认为从解释和键中得到的信息并不准确。您的键似乎是未优化的单列索引。例如,拥有复合键(col1、col2、col3)会有所帮助。

我用别名重写了您的查询以简化一些。还为自己格式化以直观地查看表之间的显式关系。我还将班级状态移动到 JOIN 组件到班级表中。

SELECT
      H.id AS homework_id,
      H.description
   FROM 
      Homework H
         JOIN student_homework_assn SHA
            ON H.id = SHA.homework_id
            JOIN class_student_assn CSA
               ON SHA.student_id = CSA.student_id
               JOIN class C
                  ON CSA.class_id = C.id
                 AND C.class_status_id = 2
   WHERE 
          H.grade IS NULL
      AND H.homework_date > DATE_ADD(NOW(), INTERVAL -1 DAY)
   LIMIT 
      1000;

我会建议在您各自的表上使用以下复合索引以及为什么...

table: Homework        
index: (grade, homework_date, id)   or  (homework_date, grade, id)

成绩和作业可用于分别按特定日期和成绩优化 WHERE 子句...但是,它还包括用于加入学生作业关联表的 ID。这样,数据库不必在页面级别查询每条记录来限定哪些记录满足最低标准。该 ID 也包括在加入到 student_homework_assn 表的下一级。

table: Student_Homework_Assn  
index: (homework_id, student_id)

作业 ID 与上一个作业表匹配,但学生 ID 也用于下一级...

table: class_student_assn
index: (student_id, class_id )

相似,student 匹配上一个,class 匹配下一个

table: class
index: (id, class_status_id )

最后是类和它的状态。

我会对此结果感兴趣...并且取决于您的查询,我有另一种选择

【讨论】:

  • 这很有帮助。我在H 上添加了除第一个索引(grade, homework_date, id) 之外的所有索引(因为该表有200M 行,这需要很长时间)。但我能够让查询在 ~1 秒内返回!我还将homework_date 子句移到了更小的SHA 表中。
  • 我还学到了很多关于您如何看待索引的知识。感谢那。我也很好奇您的替代查询的方向。
  • @Ryan,我的候补人员会从 CLASS 表开始,将特定状态作为主要标准,然后过滤到学生/班级和家庭作业。如果您有 3k 个课程,但只有 250 个是 status = 2(或其他),您将立即忽略与其他 2750 个课程相关的任何家庭作业。
  • @Ryan,不一定,但它有助于了解较小粒度数据的预期位置。如果您可以对此进行磨练,而不是向下查看宇宙中的所有内容,那么您就知道自己在寻找什么,您是否有办法直接指向该元素,然后再兜售以获取其他元素。希望有道理,很高兴你现在不到 1 秒。
  • @Ryan,一个这样的例子......例如,您有一个销售订单详细信息的主表。订单有大量对辅助表的查找,例如订单 ID、itemID、订单状态代码等……如果您从较小的订单状态代码表开始返回销售项目,则不一定有效。核心是销售项目。
猜你喜欢
  • 2022-01-08
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-13
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多