为什么SELECT语句的速度会在特定的LIMIT数量下急剧变化?

时间:2016-07-19 17:50:52

标签: mysql innodb

我在MySQL中运行以下简单查询:

SELECT SQL_NO_CACHE longitude, latitude FROM pins ORDER BY pin_id LIMIT 100000

这大约需要0.08秒。但是,如果我将LIMIT提高到120000,则需要将近一整秒才能完成。我来回跑了多次。它是非常一致的,大约100700它可以走任何一种方式,有时是缓慢的,有时是快速的。关于发生了什么的任何想法?

EXPLAIN

(有LIMIT 100000)

id select_type table type  possible_keys key     key_len ref  rows   Extra  
1  SIMPLE      pins  index NULL          PRIMARY 4       NULL 100000 

(有LIMIT 200000)

id select_type table type  possible_keys key     key_len ref  rows   Extra  
1  SIMPLE      pins  index NULL          PRIMARY 4       NULL 200000 

其他信息

表尺寸:200M
innodb_buffer_pool_size:8G
服务器上还有另一个200GB的数据库。

更新1

我重置了我的服务器,事情似乎已修复。查询占用的时间与LIMIT成正比。我仍然想知道发生了什么,所以在制作过程中不会发生。

更新2

有一个新问题。我试图在phpMyAdmin中运行查询,它只是挂起并显示“正在加载”消息。我已经尝试了多次,似乎我根本无法通过phpMyAdmin运行查询。通过PHP运行它没有问题。

1 个答案:

答案 0 :(得分:0)

你有pin_id的索引吗?或者是PRIMARY KEY

buffer_pool由16KB块组成。它们根据需要来自磁盘,并以最近最少使用(LRU)的顺序删除(大致)。

重启服务器,然后执行以下操作:

  1. SELECT ... LIMIT 100000; - 缓慢因为没有缓存
  2. SELECT ... LIMIT 100000; - 快速,因为所有数据都被缓存
  3. SELECT ... LIMIT 120000; - 因为最后的20K行未缓存而缓慢
  4. SELECT ... LIMIT 120000; - 快速,因为所有数据都被缓存
  5. SELECT ... LIMIT 100000; - 仍然很快(仍然缓存)
  6. 由于你有8GB的buffer_pool和120000行(我假设)很容易适合,我们还没有从缓存中溢出。 (我还假设没有其他查询从这个或其他表中填充缓冲池。)

    现在,让我们假设您的表太大,以至于以下内容不适合buffer_pool:

    1. SELECT ... LIMIT 99999999; - 因为并非所有缓存都很慢
    2. SELECT ... LIMIT 99999999; - 再慢一点!因为从缓存溢出而且东西必须从磁盘重新加载
    3. 但是,你提到了其他的东西......这张表只有200M。如果那是 bytes ,那么我的最后一对选择不适用。如果它是,则可能超过8GB。

      但是......你提到了200GB的另一个数据库。它的16KB块也来自buffer_pool。所以它上面的活动可能会撞出你的桌子。