【问题标题】:MySQL: How to make an Index Scan run faster than a Full Table Scan?MySQL:如何使索引扫描比全表扫描运行得更快?
【发布时间】:2011-09-17 13:07:28
【问题描述】:

我从MySQL Performance Blog 中了解到,根据查询的选择性,全表扫描可能比索引扫描更快。考虑到这些知识,我根据我之前的post 在一个有 500 万行的表上尝试了一个具有 12 个WHERE 条件和一个HAVING 条件的查询。我观察到全表扫描(7.7sec)仍然比具有 3% 选择性(161341/ 5000000)。

我的问题是:“为什么选择性为 3% 的索引扫描仍然比全表扫描慢 20 倍?有没有办法让索引扫描更快?

【问题讨论】:

  • 对于上述比较,我在运行查询之前做了一个echo 3 > /proc/sys/vm/drop_caches 来刷新系统缓存。如果我不刷新缓存,则使用索引扫描的后续查询总是更快。 Flush tables 命令在这里不影响查询速度。
  • 在对您之前帖子的评论中说,上面的执行时间是在 SQL 的第一次执行时测量的。如果你多次执行它们,性能差异是否相同?
  • @Klas Lindbäck:如果我每次在每次查询之前都进行一次刷新(参见我的第一条评论),那么索引扫描总是比完全扫描慢得多。
  • 这个问题似乎与如何将表加载到缓存中有关。当您执行全表扫描时,使用顺序读取读取表。我的猜测是,当您使用索引时,将按照它们在索引中出现的顺序读取块,即非顺序。但这取决于您的存储解决方案。

标签: mysql query-optimization


【解决方案1】:

四列索引的索引扫描

索引中列的顺序会影响性能。将最具选择性的列放在索引的首位。它还取决于您的查询。带有'x LIKE '%foo%' 的 WHERE 子句不会有效地使用索引,但'x LIKE 'foo%' 会更有效。

【讨论】:

  • 在另一个posting 中提到,如果查询使用索引的所有列,则顺序没有区别。
  • 您可以查看我的查询here。使用的索引是 (act, Type, tn, flA)。
  • 很难判断哪一列是最具选择性的列,因为一个查询可以在 A 列上具有选择性,而另一个查询可以在 B 列上具有选择性,依此类推。
  • @Ben:然后你可以添加多个索引,让优化器为每个查询选择最好的一个。请注意,索引不是免费的:它需要额外的磁盘空间并且插入/更新时间会更慢。
  • 好的,我将通过反转索引中的列序列来测试它。但是从应用程序的角度来看,很难判断哪个是最具选择性的列,因为一个查询可以对 A 列进行选择,而另一个查询可以对 B 列进行选择,依此类推。
猜你喜欢
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 2021-09-04
  • 2016-08-10
相关资源
最近更新 更多