上面id的值跨度太大,1所在的页和200万所在页中间有很多页需要读取,所以比较慢 。in的检索
所以使用between and的时候,区间跨度不要太大 。
in方式检索数据,我们还是经常用的 。mysql> select * from test1 a where a.id in (100000, 100001, 100002, 100003, 100004, 100005, 100006, 100007, 100008, 100009, 100010, 100011, 100012, 100013, 100014, 100015, 100016, 100017, 100018, 100019, 100020, 100021, 100022, 100023, 100024, 100025, 100026, 100027, 100028, 100029, 100030, 100031, 100032, 100033, 100034, 100035, 100036, 100037, 100038, 100039, 100040, 100041, 100042, 100043, 100044, 100045, 100046, 100047, 100048, 100049, 100050, 100051, 100052, 100053, 100054, 100055, 100056, 100057, 100058, 100059, 100060, 100061, 100062, 100063, 100064, 100065, 100066, 100067, 100068, 100069, 100070, 100071, 100072, 100073, 100074, 100075, 100076, 100077, 100078, 100079, 100080, 100081, 100082, 100083, 100084, 100085, 100086, 100087, 100088, 100089, 100090, 100091, 100092, 100093, 100094, 100095, 100096, 100097, 100098, 100099);+--------+----------------+-----+------------------------+| id | name | sex | email |+--------+----------------+-----+------------------------+| 100000 | javacode100000 | 2 | javacode100000@163.com || 100001 | javacode100001 | 1 | javacode100001@163.com || 100002 | javacode100002 | 2 | javacode100002@163.com |.......| 100099 | javacode100099 | 1 | javacode100099@163.com |+--------+----------------+-----+------------------------+100 rows in set (0.00 sec)
平时我们做项目的时候,建议少用表连接,比如电商中需要查询订单的信息和订单中商品的名称,可以先查询查询订单表,然后订单表中取出商品的id列表,采用in的方式到商品表检索商品信息,由于商品id是商品表的主键,所以检索速度还是比较快的 。
通过id在400万数据中检索100条数据,看看效果:
耗时不到1毫秒,还是相当快的 。多个索引时查询如何走?
这个相当于多个分解为多个唯一记录检索,然后将记录合并 。
我们在name、sex两个字段上分别建个索引mysql> create index idx1 on test1(name);Query OK, 0 rows affected (13.50 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> create index idx2 on test1(sex);Query OK, 0 rows affected (6.77 sec)Records: 0 Duplicates: 0 Warnings: 0看一下查询:
mysql> select * from test1 where name='javacode3500000' and sex=2;+---------+-----------------+-----+-------------------------+| id | name | sex | email |+---------+-----------------+-----+-------------------------+| 3500000 | javacode3500000 | 2 | javacode3500000@163.com |+---------+-----------------+-----+-------------------------+1 row in set (0.00 sec)
上面查询速度很快,name和sex上各有一个索引,觉得上面走哪个索引?我们看一下name='javacode3500000'检索速度,确实很快,如下:
有人说name位于where第一个,所以走的是name字段所在的索引,过程可以解释为这样:
走name所在的索引找到javacode3500000对应的所有记录
遍历记录过滤出sex=2的值
mysql> select * from test1 where name='javacode3500000';+---------+-----------------+-----+-------------------------+| id | name | sex | email |+---------+-----------------+-----+-------------------------+| 3500000 | javacode3500000 | 2 | javacode3500000@163.com |+---------+-----------------+-----+-------------------------+1 row in set (0.00 sec)走name索引,然后再过滤,确实可以,速度也很快,果真和where后字段顺序有关么?我们把name和sex的顺序对调一下,如下:
mysql> select * from test1 where sex=2 and name='javacode3500000';+---------+-----------------+-----+-------------------------+| id | name | sex | email |+---------+-----------------+-----+-------------------------+| 3500000 | javacode3500000 | 2 | javacode3500000@163.com |+---------+-----------------+-----+-------------------------+1 row in set (0.00 sec)速度还是很快,这次是不是先走sex索引检索出数据,然后再过滤name呢?我们先来看一下sex=2查询速度:
mysql> select count(id) from test1 where sex=2;+-----------+| count(id) |+-----------+| 2000000 |+-----------+1 row in set (0.36 sec)看上面,查询耗时360毫秒,200万数据,如果走sex肯定是不行的 。
我们使用explain来看一下:
mysql> explain select * from test1 where sex=2 and name='javacode3500000';+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+| 1 | SIMPLE | test1 | NULL | ref | idx1,idx2 | idx1 | 62 | const | 1 | 50.00 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+1 row in set, 1 warning (0.00 sec)
推荐阅读
- Mysql性能优化之逐级优化,开发人员必备技巧
- 如何去床上螨虫最快方法 干货满满床上除螨虫的简单方法速来了解
- 教你如何用 openresty 完美替换 nginx
- MySQL锁详细讲解
- 数据库架构举例说明
- 看资深站长教你如何做好网站运营
- 如何实现交换机不同VLAN、不同网段之间互访?
- 筒灯尺寸一般是多少 如何选择筒灯尺寸
- 患有鼻窦炎如何排脓
- 鼻窦炎引起的低烧如何治疗