您现在的位置是:首页 > 数码 > 

mysql普通索引命中

2025-07-18 16:05:37
mysql普通索引命中 什么是索引?为什么要建立索引? 索引用于快速出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一个位置去搜索

mysql普通索引命中

什么是索引?为什么要建立索引?

索引用于快速出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一个位置去搜索数据文件,而不必查看所有数据,那么将会节省很大一部分时间。

例如:有一张person表,其中有2W条记录,记录着2W个人的信息。有一个Phone的字段记录每个人的电话号码,现在想要查询出电话号码为xxxx的人的信息。

如果没有索引,那么将从表中第一条记录一条条往下遍历,直到到该条信息为止。

如果有了索引,那么会将该Phone字段,通过一定的方法进行存储,好让查询该字段上的信息时,能够快速到对应的数据,而不必在遍历2W条数据了。其中MySQL中的索引的存储类型有两种:BTREE、HASH。 也就是用树或者Hash值来存储该字段,要知道其中详细是如何查的,就需要会算法的知识了。我们现在只需要知道索引的作用,功能是什么就行。

引言

今天写了一个sql,其中涉及的表中的数据量都差不多为50w左右,查询发现用了8s。这个只是测试服上数据,放到正式服上,肯定一运行就挂了。

SELECT

Orders. O,

Guido,

Orders.CreateTime,

sum(OrderItem.Quantity) AS Quantity,

Brand. AME AS Brandame,

member.Mobile,

Street AS deliveryaddress,

Area

FROM

Orders

IER JOI OrderItem O Orders.Guido = OrderItem.OrderGuido

IER JOI Brand O Brand.Id = Orders.BrandId

IER JOI member O member.Id = 1

IER JOI memberaddress O member.Id = memberaddress.MemberId

WHERE

orders.Guido I (

SELECT

orderpayment.OrderGuido

FROM

paymentrecord

LEFT JOI orderpayment O paymentrecord.`o` = orderpayment.Paymento

WHERE

paymentrecord.PaymentMethod = MemberCard

AD paymentrecord.Payer = 1

)

GROUP BY

Guido;

然后就用EXPLAI分析了一下,发现Orders表没有命中索引,但是查询Orders中的Guido已经设置了索引,但就是不能命中。

解决过程

然后我将上面的语句分为两个语句。首先将sql语句修改为:将子查询的数据直接写在了sql中,查询用了0.12s。

SELECT

Orders. O,

Guido,

Orders.CreateTime,

sum(OrderItem.Quantity) AS Quantity,

Brand. AME AS Brandame,

member.Mobile,

Street AS deliveryaddress,

Area

FROM

Orders

IER JOI OrderItem O Orders.Guido = OrderItem.OrderGuido

IER JOI Brand O Brand.Id = Orders.BrandId

IER JOI member O member.Id = 1

IER JOI memberaddress O member.Id = memberaddress.MemberId

WHERE

orders.Guido I (

0A499C5B1A82B622AE99D107D4DA7B8 ,

18A5EE6B1D4E9D76B646D2F6B86442 ,

27A5AE2BACEA714F8B907865F08450 ,

B42B085E794BA14516CE21C1CF8187 ,

FBC978E1602ED42E5567168E7F0602

)

GROUP BY

Guido

第二个:单独运行子查询的Sql,也才用了0.1s

SELECT

orderpayment.OrderGuido

FROM

paymentrecord

LEFT JOI orderpayment O paymentrecord.`o` = orderpayment.Paymento

WHERE

paymentrecord.PaymentMethod = MemberCard

AD paymentrecord.Payer = 1

这么问题就清晰了,一定是子查询和父查询关联的问题。因为子查询单独很快,父查询用子查询数据直接查的时候也很快,就是在他俩结合的时候很慢。大致能将问题锁定在这两个关联字段OrderGuido上。

最后发现 orderpayment 表和 Orders 表字符集是不同的。一个表的字符集是:utf8_general_ci,一个是:utf8_general_ci。(不查不知道,发现一个数据库中,很多表的字符集都不相同)

修改orderpayment表的字符集和表中OrderGuido的字符集为:utf8_general_ci

ALTER TABLE orderpayment DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; //修改表的字符集

ALTER TABLE orderpayment CHAGE OrderGuido OrderGuido VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci; //修改字段的字符集

然后在用EXPLAI分析一下,可以看到都用上了索引。

然后运行,查询了0.112秒。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/shuma/794868.html

相关标签:无
上传时间: 2024-01-10 12:22:19
留言与评论(共有 11 条评论)
本站网友 笑傲江湖吕颂贤
18分钟前 发表
HASH
本站网友 上海房屋合租
17分钟前 发表
Brand. AME AS Brandame
本站网友 老家锅贴
5分钟前 发表
member.Mobile
本站网友 新房
5分钟前 发表
Street AS deliveryaddress
本站网友 廊坊印刷公司
22分钟前 发表
18A5EE6B1D4E9D76B646D2F6B86442
本站网友 婉君表妹
15分钟前 发表
sum(OrderItem.Quantity) AS Quantity
本站网友 crx文件
30分钟前 发表
也就是用树或者Hash值来存储该字段,要知道其中详细是如何查的,就需要会算法的知识了
本站网友 中钢吉电
11分钟前 发表
HASH
本站网友 长风破浪会有时的下一句
17分钟前 发表
member.Mobile
本站网友 n95口罩多久换一次
7分钟前 发表
FBC978E1602ED42E5567168E7F0602 ) GROUP BY Guido 第二个:单独运行子查询的Sql,也才用了0.1s SELECT orderpayment.OrderGuido FROM paymentrecord LEFT JOI orderpayment O paymentrecord.`o` = orderpayment.Paymento WHERE paymentrecord.PaymentMethod = MemberCard AD paymentrecord.Payer = 1 这么问题就清晰了,一定是子查询和父查询关联的问题