> 数据库 > MySQL >

mysql distinct和group by谁更好

今天无意中听到有同事在讨论,distinct和group by谁的速度会更快一点,意件不一,其实我也不知道那个好,下午有时间做了一下测试。

 

1,测试前的准备

查看复制打印?
  1. //准备一张测试表  
  2. mysql> CREATE TABLE `test_test` (  
  3.  ->   `id` int(11) NOT NULL auto_increment,  
  4.  ->   `num` int(11) NOT NULL default '0',  
  5.  ->   PRIMARY KEY  (`id`)  
  6.  -> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;  
  7. Query OK, 0 rows affected (0.05 sec)  
  8.   
  9. mysql> delimiter ||  //改变mysql命令结束符为||  
  10.   
  11. //建个储存过程向表中插入10W条数据  
  12. mysql> create procedure p_test(pa int(11))  
  13.  -> begin  
  14.  ->  
  15.  ->  declare max_num int(11) default 100000;  
  16.  ->  declare i int default 0;  
  17.  ->  declare rand_num int;  
  18.  ->  
  19.  ->  select count(id) into max_num from test_test;  
  20.  ->  
  21.  ->  while i < pa do  
  22.  ->          if max_num < 100000 then  
  23.  ->                  select cast(rand()*100 as unsigned) into rand_num;  
  24.  ->                  insert into test_test(num)values(rand_num);  
  25.  ->          end if;  
  26.  ->          set i = i +1;  
  27.  ->  end while;  
  28.  -> end||  
  29. Query OK, 0 rows affected (0.00 sec)  
  30.   
  31. mysql> call p_test(100000)||  
  32. Query OK, 1 row affected (5.66 sec)  
  33.   
  34. mysql> delimiter ;//改变mysql命令结束符为;  
  35. mysql> select count(id) from test_test;  //数据都进去了  
  36. +-----------+  
  37. count(id) |  
  38. +-----------+  
  39. |    100000 |  
  40. +-----------+  
  41. 1 row in set (0.00 sec)  
  42.   
  43. mysql> show variables like "%pro%";   //查看一下,记录执行的profiling是不是开启动了,默认是不开启的  
  44. +---------------------------+-------+  
  45. | Variable_name             | Value |  
  46. +---------------------------+-------+  
  47. | profiling                 | OFF   |  
  48. | profiling_history_size    | 15    |  
  49. | protocol_version          | 10    |  
  50. | slave_compressed_protocol | OFF   |  
  51. +---------------------------+-------+  
  52. 4 rows in set (0.00 sec)  
  53.   
  54. mysql> set profiling=1;           //开启  
  55. Query OK, 0 rows affected (0.00 sec)  

2,测试

查看复制打印?
  1. //做了4组测试  
  2. mysql> select distinct(num) from test_test;  
  3. mysql> select num from test_test group by num;  
  4.   
  5. mysql> show profiles;    //查看结果  
  6. +----------+------------+-------------------------------------------+  
  7. | Query_ID | Duration   | Query                                     |  
  8. +----------+------------+-------------------------------------------+  
  9. |        1 | 0.07298225 | select distinct(num) from test_test       |  
  10. |        2 | 0.07319975 | select num from test_test group by num    |  
  11. |        3 | 0.07313525 | select num from test_test group by num    |  
  12. |        4 | 0.07317725 | select distinct(num) from test_test       |  
  13. |        5 | 0.07275200 | select distinct(num) from test_test       |  
  14. |        6 | 0.07298600 | select num from test_test group by num    |  
  15. |        7 | 0.07500700 | select num from test_test group by num    |  
  16. |        8 | 0.07331325 | select distinct(num) from test_test       |  
  17. |        9 | 0.57831575 | create index num_index on test_test (num) |  //在这儿的时候,我加了索引  
  18. |       10 | 0.00243550 | select distinct(num) from test_test       |  
  19. |       11 | 0.00121975 | select num from test_test group by num    |  
  20. |       12 | 0.00116550 | select distinct(num) from test_test       |  
  21. |       13 | 0.00107650 | select num from test_test group by num    |  
  22. +----------+------------+-------------------------------------------+  
  23. 13 rows in set (0.00 sec)  

上面的1-8是4组数据,并且是没有加索引的,从中我们可以看出,distinct比group by 会好一点点

10-13是2组数据,是加了索引以后的,从中我们可以看出,group by 比distinct 会好一点点

一般情况,数据量比较大的表,关联字段都会加索引的,,并且加索引后检索时间只有以前的六分之一左右。

(责任编辑:IT)