Home > mysql, sql优化 > STRAIGHT_JOIN has no effect on query with subquery in FROM clause

STRAIGHT_JOIN has no effect on query with subquery in FROM clause

上周的mysql官网上提交了一个bug,原因为在我们的一个分页sql中出现了全表扫描的情况,这对于我们来说是不可接受的:

root@test 02:06:16>explain select t.*
    ->      from (select id
    ->              from bbs_0009 g force index (ind_group_type_time)
    ->             where g.g_id = 154505
    ->                and g.deleted = 0
    ->                and (g.verify != 0 OR g.verify IS NULL)
    ->                and board_id = 50555
    ->                and (g.type = 0 or g.type = 2)
    ->              order by g.reply_time desc limit 840, 40) g,
    ->            bbs_0009 t
    ->      where t.id = g.id;

+—-+————-+————+——–+———————+———+———+——+——–+—————-+

| id | select_type | table      | type   | possible_keys       | key     | key_len | ref  | rows   | Extra

|+—-+————-+————+——–+———————+———+———+——+——–+—————-+

|  1 | PRIMARY     | <derived2> | ALL    | NULL                | NULL    | NULL    | NULL |      9 |                |

|  1 | PRIMARY     | t          | eq_ref | PRIMARY             | PRIMARY | 8       | g.id |      1 |                |

|  2 | DERIVED     | g          | ALL    | ind_group_type_time | NULL    | NULL    | NULL | 652469 | Using filesort

|+—-+————-+————+——–+———————+———+———+——+——–+——–

3 rows in set (0.54 sec)

ind_group_type_time:g_id,type,reply_time,deleted,digest,board_id
category,verify(表中定义查询字段的数据类型与查询的数据的数据类型一致)

可以看到在内查询中即使加入了force index 也没有上查询走上索引,而是走了全表扫,如果将其单独拿出来执行,而不做关联查询的话,是可以用上覆盖索引:

query 2 explain : root@test 02:06:18>explain select id
    ->              from bbs_0009 g force index (ind_group_type_time)
    ->             where g.g_id = 154505
     ->                and g.deleted = 0
    ->                and (g.verify != 0 OR g.verify IS NULL)
    ->                and board_id = 50555
    ->                and (g.type = 0 or g.type = 2)
    ->              order by g.reply_time desc limit 840, 40;

+—-+————-+——-+——-+———————+———————+——–

| id | select_type | table | type  | possible_keys       | key                 | key_len | ref  | rows   ||

+—-+————-+——-+——-+———————+———————+——–

|  1 | SIMPLE      | g     | range | ind_group_type_time | ind_group_type_time | 9       | NULL | 326235 | Using where; Using index; Using filesort |

+—-+————-+——-+——-+———————+———————+——-

 

在和官网的Valeriy Kravchuk多次沟通后,最终认为这是一个bug;最后解决的办法是调整索引,来避免排序的,这样就能够使用覆盖索引索引:

ind_group_type_time:g_id,reply_time,type,deleted,digest,board_id
category,verify

因此大家对这种类型的分页语句一定多加注意,由于排序导致全表扫描的问题;

Categories: mysql, sql优化 Tags:
  1. No comments yet.
  1. No trackbacks yet.
You must be logged in to post a comment.