什么是索引?为什么要建立索引?
索引用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一个位置去搜索数据文件,而不必查看所有数据,那么将会节省很大一部分时间。
例如:有一张person表,其中有2W条记录,记录着2W个人的信息。有一个Phone的字段记录每个人的电话号码,现在想要查询出电话号码为xxxx的人的信息。
如果没有索引,那么将从表中第一条记录一条条往下遍历,直到找到该条信息为止。
如果有了索引,那么会将该Phone字段,通过一定的方法进行存储,好让查询该字段上的信息时,能够快速找到对应的数据,而不必在遍历2W条数据了。其中MySQL中的索引的存储类型有两种:BTREE、HASH。 也就是用树或者Hash值来存储该字段,要知道其中详细是如何查找的,就需要会算法的知识了。我们现在只需要知道索引的作用,功能是什么就行。
引言
今天写了一个sql,其中涉及的表中的数据量都差不多为50w左右,查询发现用了8s。这个只是测试服上数据,放到正式服上,肯定一运行就挂了。
SELECT Orders. NO, GuidNo, Orders.CreateTime, sum(OrderItem.Quantity) AS Quantity, Brand. NAME AS BrandName, member.Mobile, Street AS deliveryaddress, Area FROM Orders INNER JOIN OrderItem ON Orders.GuidNo = OrderItem.OrderGuidNo INNER JOIN Brand ON Brand.Id = Orders.BrandId INNER JOIN member ON member.Id = 13 INNER JOIN memberaddress ON member.Id = memberaddress.MemberId WHERE orders.GuidNo IN ( SELECT orderpayment.OrderGuidNo FROM paymentrecord LEFT JOIN orderpayment ON paymentrecord.`No` = orderpayment.PaymentNo WHERE paymentrecord.PaymentMethod = 'MemberCard' AND paymentrecord.Payer = 13 ) GROUP BY GuidNo;
然后就用EXPLAIN分析了一下,发现Orders表没有命中索引,但是查询Orders中的GuidNo已经设置了索引,但就是不能命中。
解决过程
然后我将上面的语句分为两个语句。首先将sql语句修改为:将子查询的数据直接写在了sql中,查询用了0.12s。
SELECT Orders. NO, GuidNo, Orders.CreateTime, sum(OrderItem.Quantity) AS Quantity, Brand. NAME AS BrandName, member.Mobile, Street AS deliveryaddress, Area FROM Orders INNER JOIN OrderItem ON Orders.GuidNo = OrderItem.OrderGuidNo INNER JOIN Brand ON Brand.Id = Orders.BrandId INNER JOIN member ON member.Id = 13 INNER JOIN memberaddress ON member.Id = memberaddress.MemberId WHERE orders.GuidNo IN ( '0A499C5B1A82B6322AE99D107D4DA7B8', '18A5EE6B1D4E9D76B6346D2F6B836442', '327A5AE2BACEA714F8B907865F084503', 'B42B085E794BA14516CE21C13CF38187', 'FBC978E1602ED342E5567168E73F0602' ) GROUP BY GuidNo
第二个:单独运行子查询的Sql,也才用了0.1s
SELECT orderpayment.OrderGuidNo FROM paymentrecord LEFT JOIN orderpayment ON paymentrecord.`No` = orderpayment.PaymentNo WHERE paymentrecord.PaymentMethod = 'MemberCard' AND paymentrecord.Payer = 13
这么问题就清晰了,一定是子查询和父查询关联的问题。因为子查询单独很快,父查询用子查询数据直接查的时候也很快,就是在他俩结合的时候很慢。大致能将问题锁定在这两个关联字段OrderGuidNo上。
最后发现 orderpayment 表和 Orders 表字符集是不同的。一个表的字符集是:utf8_general_ci,一个是:utf8mb4_general_ci。(不查不知道,发现一个数据库中,很多表的字符集都不相同)
修改orderpayment表的字符集和表中OrderGuidNo的字符集为:utf8_general_ci
ALTER TABLE orderpayment DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; //修改表的字符集 ALTER TABLE orderpayment CHANGE OrderGuidNo OrderGuidNo VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci; //修改字段的字符集
然后在用EXPLAIN分析一下,可以看到都用上了索引。
然后运行,查询了0.112秒。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]