MySQL 5.7 下 distinct 和 group by 效率性能比较

MySQL 5.7 下 distinct 和 group by 效率性能比较

  • 前言
    • 环境
    • 数据
    • 表结构
    • 测试开始
      • 测试范围
      • 测试 1(不使用 where)
      • 测试 2(使用 where 语句,id < 100000)
      • 测试 3(使用 where 语句,id < 500000)
      • 测试 4(使用 where 语句,id < 1000000)
      • 测试 5(使用 where 语句,1586448000000 < time < 1587312000000)
  • 结论

前言

环境

腾讯云旗下的 MySQL 5.7 数据库基础版,IOPS:2300,1 核 1000MB 规格。

数据

来自微博各地的签到数据共 150 多万条记录。

表结构

  1. 表名(weibo.checkin_list)
  2. 主键(id)
  3. 普通升序索引(place_code,地点代码,varchar(255))
  4. 普通升序索引(create_time,发表时间,13 位时间戳,bigint)
  5. 以及其他字段

测试开始

测试范围

分别对上述表进行 distinct 和 group by 操作,操作字段为普通升序索引(place_code)。分别使用 where 语句限定范围和不使用 where 语句。

测试 1(不使用 where)

distinct 语句:

select distinct place_code
from weibo.checkin_list;

group by 语句:

select place_code
from weibo.checkin_list
group by place_code
order by null;

结果
distinct 语句用时浮动范围:250ms - 300ms。
group by 语句用时浮动范围:200ms - 250ms。
explain 结果
两者都一样

id select_type table patitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE checkin_list range checkin_list_place_code_index checkin_list_place_code_index 1023 86930 100 Using index for group-by

测试 2(使用 where 语句,id < 100000)

distinct 语句:

select distinct place_code
from weibo.checkin_list
where id < 100000;

group by 语句:

select place_code
from weibo.checkin_list
where id < 100000
group by place_code
order by null;

结果
distinct 语句用时浮动范围:250ms - 350ms。
group by 语句用时浮动范围:350ms - 400ms。
explain 结果
两者都一样

id select_type table patitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE checkin_list range “PRIMARY,checkin_list_place_code_index” PRIMARY 4 104452 100 Using where; Using temporary

测试 3(使用 where 语句,id < 500000)

distinct 语句:

select distinct place_code
from weibo.checkin_list
where id < 500000;

group by 语句:

select place_code
from weibo.checkin_list
where id < 500000
group by place_code
order by null;

结果
distinct 语句用时浮动范围:250ms - 350ms。
group by 语句用时浮动范围:1200ms - 1500ms。
explain 结果
同上

测试 4(使用 where 语句,id < 1000000)

distinct 语句:

select distinct place_code
from weibo.checkin_list
where id < 1000000;

group by 语句:

select place_code
from weibo.checkin_list
where id < 1000000
group by place_code
order by null;

结果
distinct 语句用时浮动范围:250ms - 350ms。
group by 语句用时浮动范围:2200ms - 2500ms。
explain 结果
同上

测试 5(使用 where 语句,1586448000000 < time < 1587312000000)

distinct 语句:

select distinct place_code
from weibo.checkin_list
where create_time > 1586448000000
  and create_time < 1587312000000
limit 5000;

group by 语句:

select place_code
from weibo.checkin_list
where create_time > 1586448000000
  and create_time < 1587312000000
group by place_code
order by null
limit 5000;

结果
distinct 语句用时浮动范围:350ms - 400ms,第一次查询高达 1000ms。
group by 语句用时浮动范围:1500ms - 3000ms,有时高达 7000ms+,第一次查询也会 7000ms+。
explain 结果

id select_type table patitions type possible_keys key key_len ref rows filtered Extra
distinct SIMPLE checkin_list ALL “checkin_list_create_time_index ,checkin_list_place_code_index” 1333215 50 Using where; Using temporary
group by SIMPLE checkin_list index “checkin_list_create_time_index,checkin_list_place_code_index” checkin_list_place_code_index 1023 153340 50 Using where

结论

因为不怎么会看 explain 的结果(不太懂 MySQL 原理),所以就仅仅将结果放在上面,希望能有人来解读。
在上述测试中,可以发现,在对单一字段进行去重的语句上:

distinct group by
不使用 where 高效,250ms - 300ms 高效,200ms - 250ms
使用 where 高效,250ms - 350ms,初次查询可能 1000ms 低效,1000ms - 2500ms,初次查询可以高达 7000ms

特别注意
本结论仅限于本人使用的服务器和数据。

你可能感兴趣的:(数据库,mysql,数据库,sql)