【问题标题】:Optimize MySQL self join query优化 MySQL 自连接查询
【发布时间】:2014-01-04 22:09:17
【问题描述】:

我需要从表中选择满足特定条件的行对。
这是一个演示我想要的 SQL 小提琴:

http://sqlfiddle.com/#!2/4fc2f/16/0

这在表格很小的情况下效果很好——但问题是我的生产表格可能有数百万行和特定日期的数千行。查询现在需要 14-15 秒才能运行特定日期。我该如何改进它?

MySQL 5.5

【问题讨论】:

  • 你有索引吗?做一个show create table。顺便说一句,访问数百万行的查询需要 14 秒并不是那么糟糕
  • 是的,这里显示的所有列都有索引(表中有更多列,但我正在简化)。对特定日期的直接选择似乎几乎立即发生(

标签: mysql sql optimization


【解决方案1】:

您缺少索引。尝试使用 EXPLAIN 来分析您的查询,它将对您有很大帮助。

解决方法很简单,如下: http://sqlfiddle.com/#!2/56deb/1/0

您需要添加一个索引,其中包含 where 语句中使用的列,以便它们被使用:

KEY `night_of_2` (`night_of`,`student_id`,`check_class`)

您还需要在连接时强制使用索引,因为您将表连接到自身:

JOIN checks checks2

FORCE INDEX (night_of_2) ON (checks1.night_of = checks2.night_of)

(如果有更好的方法我想知道):)

问候,

【讨论】:

  • 这里没有任何建议强制索引是必需的(这是一个非常糟糕的主意,除非你绝对必须这样做)。添加我们都建议的索引后,强制使用此索引会导致查询效率降低(检查更多行)。
  • 感谢您的帮助!添加索引花了将近一个小时,但现在查询很好而且很快。根据 symcbean 的建议,我确实省略了 FORCE INDEX。
  • 如果您不介意,我会对查询结果感兴趣,还包括力索引(速度和或解释)。将不胜感激:)
【解决方案2】:

您的索引不是特别有效 - 您可以在一个索引中有多个列。但是为了获得正确的索引,您需要查看在数据库上运行的每个查询、每个查询的频率以及数据的分布。或者你只是要求我们做你的功课?根据提供的信息,使用 (night_of, check_class, student_id) 上的索引查询会更有效,并且会丢失除 PK 之外的现有索引。

【讨论】:

  • 感谢您花时间回答我的问题。您对我的索引问题确实是正确的,但是根据我的数据分布,按照 Sinisa 的建议排序索引(night_of、student_id、check_class)似乎更有效。也感谢您对省略 FORCE INDEX 的评论。
猜你喜欢
  • 2017-04-04
  • 2020-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 2020-05-10
  • 2010-10-31
  • 2020-02-14
相关资源
最近更新 更多