2013-05-31 109 views
1

当我向列添加索引时,这会如何减慢执行时间? 试图摆脱慢速查询日志中的查询。 我慢查询设置:添加索引增加查询执行

slow_query_log = 1 
long_query_time = 1 # seconds 
log_queries_not_using_indexes = 1 
slow_query_log_file = /var/log/mysql-slow.log 

describe table index slows query

+0

您使用的是InnoDB还是MyISAM? – neelsg

+0

我正在使用MyISAM – michalzuber

+2

如果您想对基准查询进行基准测试,请添加'SQL_NO_CACHE',因为第二个查询可以从mysql缓存中获取结果,结果可能会受到影响 – Stephan

回答

0

取决于磁盘上的数据的结构,它可能会更快,只是加载整个DB /列,并在RAM排序/筛选它(这可能发生在没有索引存在时),而不是遍历磁盘上的稀疏索引。我不知道这是否适用于您的具体情况,或者您是否有其他问题。

4

索引并不总是加速执行。索引的作用主要取决于查询的“选择性”:整个查询处理了多少行。

通常,读取数据库(“全表扫描”)是一种高效的操作。数据库引擎知道需要读取哪些页面,并可以预读并获取它们。这种I/O经常发生在后台,处理页面处于前台。当需要下一页时,它很有可能已经在页面缓存中。

全表扫描的性能问题是表大。所以即使高效读取也需要时间。当你在寻找百万行中的一行时(“干扰针”查询),读取是浪费时间。这是索引修复的地方。

但是,假设您每页有100条记录,并且您正在阅读的记录超过1%。平均而言,每个页面都需要被读取 - 无论您是使用索引还是全表扫描。问题是索引读取比扫描读取效率低。预读机制不能帮助他们,因为读取是随机的。

这个问题可以通过称为颠簸的东西进一步加剧。如果表格不适合内存,那么每个随机读取可能是“缓存未命中”,从而导致从磁盘读取的开销。全表扫描只会读取数据,并且使用体面的预读系统,不会发生缓存未命中。

在您的示例中,您可以通过在索引中包括bannerevent(它们使用相等进行比较)和其他字段之一来提高索引的选择性。

+0

尝试添加索引“横幅”和“事件” ALTER TABLE mod_banner ADD INDEX banner_event(banner,event)',但仍超过100ms:P http://i.imgur.com/IxWoPZU.png – michalzuber

+0

删除'ORDER BY'使其立即。 http://i.imgur.com/ZUQxksi。png 但我需要一个最低'last_view' – michalzuber

+0

一个问题:如果从索引读取会伤害性能,为什么引擎不决定不使用它们? –