distinct多个字段mysql_MySQL中索引优化distinct语句及
distin。。。
MySQL通常使⽤GROUPBY(本质上是排序动作)完成DISTINCT操作,如果DISTINCT操作和ORDERBY操作组合使⽤,通常会⽤到临时表.这样会影响性能. 在⼀些情况下,MySQL可以使⽤索引优化DISTINCT操作,但需要活学活⽤.本⽂涉及⼀个不能利⽤索引完成DISTINCT操作的实例.
实例1 使⽤索引优化DISTINCT操作
create table m11 (a int, b int, c int, d int, primary key(a)) engine=INNODB;
inrt into m11 values (1,1,1,1),(2,2,2,2),(3,3,3,3),(4,4,4,4),(5,5,5,5),(6,6,6,6),(7,7,7,7),(8,8,8,8);
explain lect distinct(a) from m11;
mysql> explain lect distinct(a) from m11;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+| id | lect_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----
+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+| 1 | SIMPLE | m11 | NULL | index | PRIMARY | PRIMARY | 4 | NULL | 1 | 100.00 | Using index |+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
说明:
1 'a'列上存在主键索引,MySQL可以利⽤索引(key列值表明使⽤了主键索引)完成了DISTINCT操作.
肺泡表面活性物质2 这是使⽤索引优化DISTINCT操作的典型实例.
实例2 使⽤索引不能优化DISTINCT操作
create table m31 (a int, b int, c int, d int, primary key(a)) engine=MEMORY;
游玄都观
inrt into m31 values (1,1,1,1),(2,2,2,2),(3,3,3,3),(4,4,4,4),(5,5,5,5),(6,6,6,6),(7,7,7,7),(8,8,8,8);
explain lect distinct(a) from m31;
mysql> explain lect distinct(a) from m31;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+| id |
lect_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+| 1 | SIMPLE | m31 | NULL | ALL | NULL | NULL | NULL | NULL | 8 | 100.00 | NULL |+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
说明:
1 从查询执⾏计划看,索引没有被使⽤.
2 对⽐实例1的建表语句,只是存储引擎不同.
3 为什么主键索引没有起作⽤? 难道MEMORY存储引擎上的索引不可使⽤?
实例3 使⽤索引可以优化DISTINCT操作的Memory表
create table m33 (a int, b int, c int, d int, INDEX USING BTREE (a)) engine=MEMORY;
inrt into m33 values (1,1,1,1),(2,2,2,2),(3,3,3,3),(4,4,4,4),(5,5,5,5),(6,6,6,6),(7,7,7,7),(8,8,8,8);
explain lect distinct(a) from m33;
mysql> explain lect distinct(a) from m33;
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------+| id | lect_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------+| 1 | SIMPLE | m33 | NULL | index | NULL | a | 5 | NULL | 8 | 100.00 | NULL |+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------+
说明:
1 'a'列上存在主键索引,MySQL可以利⽤索引(key列值表明使⽤了主键索引)完成了DISTINCT操作.
2 对⽐实例2,可以发现,⼆者都使⽤了Memory引擎. 但实例3指名使⽤Btree类型的索引.
戍边将士
3 实例2没有指定使⽤什么类型的索引,MySQL将采⽤默认值. MySQL⼿册上说:
As indicated by the engine name, MEMORY tables are stored in memory. They u hash indexes by default, which makes them very fast for single-value lookups, and very uful for creating temporary tables.
结论:
生日礼品店1 看索引对查询的影响,要注意索引的类型.
2 HASH索引适合等值查找,但不适合需要有序的场景,⽽Btree却适合有序的场景.
3 看查询执⾏计划,发现索引没有被使⽤,需要进⼀步考察索引的类型.
DISTINCT不能选择多个字段的解决⽅法在实际应⽤中,我们经常要选择数据库某表中重复数据,通常我们是使⽤DISTINCT函数。
晕段子但DISTINCT只能对⼀个字段有效,⽐如:
sql="lect DISTINCT title from Table where id>0"
当我们需要列出数据中的另⼀列,⽐如:
达字开头的成语
sql="lect DISTINCT title,posttime from Table where id>0"
得出的结果就不是我们想要的了,所以我们需要⽤另外的⽅法来解决这个问题。
下⾯的是我写的SQL语句,我不知道是不是很好,但愿有更好的⼈拿出来分享⼀下:
六年级上册数学小报写法⼀:
sql = "Select DISTINCT(title),posttime From Table1 Where id>0"
输入英文
写法⼆:
sql = "Select title,posttime From Table1 Where id>0 group by title,posttime"
写法三:
sql="lect title,posttime from Table where id in (lect min(id) from Table group by title)"