欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mysql索引创建和使用细节

程序员文章站 2022-05-29 07:57:40
最近困扰自己很久的膝盖积液手术终于做完,在家养伤,逛技术博客看到easyswoole开发组成员仙士可博客有关mysql索引方面的知识,自己打算重温下。 正常业务起步数据表数据量较少,不用考虑使用索引,当后期累积的数据数量非常可观时,使用索引是提升查询的一条途径,其他的像表分区,分库分表等等。 【索引 ......

最近困扰自己很久的膝盖积液手术终于做完,在家养伤,逛技术博客看到easyswoole开发组成员仙士可博客有关mysql索引方面的知识,自己打算重温下。

正常业务起步数据表数据量较少,不用考虑使用索引,当后期累积的数据数量非常可观时,使用索引是提升查询的一条途径,其他的像表分区,分库分表等等。

 

【索引创建】

索引的创建需要考虑被创建索引的字段区分度,比如一张表里面有渠道channel,渠道可期种类不超过3种,win系,安卓系,ios系,而数据表数据量有一百万,平均下来每个渠道各是1/3也就是33万数据,这样的数据量就是否基于channel 索引区别都不会太大。

但是如果基于date字段做索引,如20200114,一年一百万,除以365天,平均下来每天300条数据。这个区分度是相当大。

同样的索引使用 33w数据查询显然效率低于300条数据。

索引可以加快mysql服务查询速度,但不是索引越多越好,因为数据insert或update的时候,存放索引的文件同样需要进行更新,这里会拖慢数据插入更新的速度,如果对数据实时性有要求的,无疑会受影响。

 

【索引使用】

组合索引:组合索引是有多个字段联合查询使用的索引,遵循从左到右依次匹配的原则

 

【索引失效】

sql拼写字段不是依照组合索引从左至右原则;

索引字段是字符串类型,sql拼接使用整型。如下:

mysql [test_db]> show create table test_users\g;
*************************** 1. row ***************************
       table: test_users
create table: create table `test_users` (
  `uid` int(11) unsigned not null auto_increment,
  `username` char(15) not null,
  `created_time` timestamp not null default current_timestamp,
  `user_id` char(11) not null default '0',
  primary key (`uid`),
  key `testindex` (`user_id`)
) engine=innodb auto_increment=1306001 default charset=utf8mb4
1 row in set (0.04 sec)

mysql [test_db]> explain select * from test_users where user_id ='1273656';
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| 1 | simple | test_users | null | ref | testindex | testindex | 44 | const | 1 | 100.00 | null |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.05 sec)

mysql [test_db]> explain select * from test_users where user_id =1273656;
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | extra |
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1 | simple | test_users | null | all | testindex | null | null | null | 306078 | 10.00 | using where |
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 3 warnings (0.04 sec)

可以发现第一条sql的 type = ref,key = testindex,第二条sql的 type = all,key = null也就是没用到任何索引而是全表扫描

未完待续...