索引覆盖是指如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据。这种查询速度非常快,称为”索引覆盖”
成都创新互联从2013年开始,先为袁州等服务建站,袁州等地企业,进行企业商务咨询服务。为袁州企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
1查询频繁 2区分度高 3长度小 4尽量能覆盖常用查询字段
索引长度直接影响索引文件的大小,影响增删改的速度,并间接影响查询速度(占用内存多)。因此对于一些长短不同的字节,我们会针对列中的值,从左往右截取部分,来建索引。但是:
1:截的越短, 重复度越高,区分度越小, 索引效果越不好
2:截的越长, 重复度越低,区分度越高, 索引效果越好,但带来的影响也越大--增删改变慢,并间影响查询速度.
所以,我们要在 区分度 + 长度 两者上,取得一个平衡( distinct 去重 )
select count (distinct left (word,6)) / count (*) from tablename;
对于一般的系统应用区别度能达到 0.1 ,索引的性能就可以接受.
alter table tablename add index word(word(4));
给字符串类型的字段建立索引效率不高,但是必须要经常查这个字段怎么建索引?
比如说一个字段url,类型是字符串。那么可以建一个字段 crcurl 来存储url字段crc32后的值,并给 crcurl 建立索引。
crc32:循环冗余校验。根据网上数据包或计算机文件等数据产生简短固定位数校验码的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者存储之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。一般来说,循环冗余校验的值都是32位的整数。
crc32 是整形,在MySQL中,给整形字段建立索引效率比较高,crc32虽然不能确保唯一性,但是无碍,相同的机率也是极小,关键是可以大大减少查询的范围,给crcurl这个字段建立索引,查询的时候带上crcurl字段就可以利用到索引。
不允许翻过100页(百度搜索一般到70页左右)
首先我们直接大数据分页limit 5000000,10 发现耗时4.41秒
接下来我们转换方式使用where条件查询,只耗时0.02秒
2次的查询结果不一致,这是因为数据被物理删除过有空洞.,因此我们可以追加软删除功能
分析:优化思路是 不查,少查,查索引,少取.
我们现在必须要查,则只查索引,不查数据,得到id.
再用id去查具体条目. 这种技巧就是延迟索引.
分析:limit是先查询再越过,也就是说我们先查询出所有数据再进行跳跃,上图我们越过500W页,还使用了inner join 内存并没有崩掉,这是因为我们子句tmp临时表中只查询了id(索引覆盖,不需要回行去磁盘找数据了)然后拿到这10个id 分别查询这10条数据 。
排序可能发生2种情况:
1:对于覆盖索引,直接在索引上查询时,就是有顺序的, using index
2:先取出数据,形成临时表做filesort(文件排序,但文件可能在磁盘上,也可能在内存中)
我们的争取目标:取出来的数据本身就是有序的! 利用索引来排序,那么什么时候发生索引排序呢?即查询索引和order by的字段是同一个字段
goods表中 cat_id与shop_price组成联合索引:
select goods_id,cat_id,shop_price from goods where cat_id=4 order by shop_price; 可以直接利用索引来排序,
using where按照shop_price索引取出的结果,本身就是有序的
select goods_id,cat_id,shop_price from goods order by click_count;
using filesort用到了文件排序,即取出的结果再次排序
重复索引是指 在同1个列(如age), 或者顺序相同的几个列(age,school), 建立了多个索引,称为重复索引,重复索引没有任何帮助,只会增大索引文件,拖慢更新速度。
冗余索引是指2个索引所覆盖的列有重叠, 称为冗余索引。比如x,m,列,加索引 index x(x), index xm(x,m) x,xm索引, 两者的x列重叠了, 这种情况,称为冗余索引. (mx, xm 不是重复的,因为列的顺序不一样)
mysql创建lower索引的方法:
1、自动创建。在表中定义一个primarykey或者unique时,MySQL数据库会自动创建一个对应的主键索引或者是唯一索引。
2、手动创建。在创建表的时候创建索引,即可给已经有的表创建索引。
解决方案:先删除唯一索引,再在当前字段创建普通索引,参考下列说明以及SQL:
普通索引
普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHEREcolumn=)或排序条件(ORDERBYcolumn)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。
唯一索引
普通索引允许被索引的数据列包含重复的值。比如说,因为人有可能同名,所以同一个姓名在同一个“员工个人资料”数据表里可能出现两次或更多次。
如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。这么做的好处:一是简化了MySQL对这个索引的管理工作,这个索引也因此而变得更有效率;二是MySQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,MySQL将拒绝插入那条新记录。也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。
删除索引
可利用ALTER TABLE或DROP INDEX语句来删除索引。类似于CREATE INDEX语句,DROP INDEX可以在ALTER TABLE内部作为一条语句处理,语法如下。
DROP INDEX index_name ON talbe_name
ALTER TABLE table_name DROP INDEX index_name
ALTER TABLE table_name DROP PRIMARY KEY
创建索引
在执行CREATE TABLE语句时可以创建索引,也可以单独用CREATE INDEX或ALTER TABLE来为表增加索引。
ALTER TABLE
ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。
ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
ALTER TABLE table_name ADD PRIMARY KEY (column_list)
上一篇给小伙伴们讲了关于SQL查询性能优化的相关技巧,一个好的查询SQL离不开合理的索引设计。这篇小二就来唠一唠怎么合理的设计一个索引来优化我们的查询速度,要是有不合理的地方...嗯..
当然啦,开个玩笑,欢迎小伙伴们指正!
通常情况下,字段类型的选择是需要根据业务来判断的,通常需要遵循以下几点。
下列各种类型表格内容来自菜鸟教程,权当备忘。
优化建议:
注意: INT(2)设置的为显示宽度,而不是整数的长度,需要配合 ZEROFILL 使用 。
例如 id 设置为 TINYINT(2) UNSIGNED ,表示无符号,可以存储的最大数值为255,其中 TINYINT(2) 没有配合 ZEROFILL 实际没有任何意义,例如插入数字200,长度虽然超过了两位,但是这个时候是可以插入成功的,查询结果同样为200;插入数字5时,同样查询结果为5。
而 TINYINT(2) 配合 ZEROFILL 后,当插入数字5时,实际存储的还是5,不过在查询是MySQL会在前面补上一个0,即查询出来的实际为 05 。
优化建议:
优化建议:
通常来说,考虑好表中每个字段应该使用什么类型和长度,建完表需要做的事情不是马上建立索引,而是先把相关主体业务开发完毕,然后把涉及该表的SQL都拿出来分析之后再建立索引。
尽量少建立单值索引( 唯一索引除外 ),应当设计一个或者两三个联合索引,让每一个联合索引都尽量去包含SQL语句中的 where、order by、group by 的字段,同时确保联合索引的字段顺序尽量满足SQL查询的最左前缀原则。
索引基数是指这个字段在表里总共有多少个不同的值,比如一张表总共100万行记录,其中有个性别字段,性别一共有三个值:男、女、保密,那么该字段的基数就是3。
如果对这种小基数字段建立索引的话,因为索引树中只有男、女、保密三个值,根本没法进行快速的二分查找,同时还需要回表查询,还不如全表扫描嘞。
一般建立索引,尽量使用那些基数比较大的字段,那么才能发挥出B+树快速二分查找的优势来。
在 where 和 order by 出现索引设计冲突时,是优先针对where去设计索引?还是优先针对order by设计索引?
通常情况下都是优先针对 where 来设计索引,因为通常情况下都是先 where 条件使用索引快速筛选出来符合条件的数据,然后对进行筛选出来的数据进行排序和分组,而 where 条件快速筛选出来的的数据往往不会很多。
对生产实际运行过程中,或者测试环境大数据量测试过程中发现的慢查询SQL进行特定的索引优化、代码优化等策略。
终于轮到实战了,小二最喜欢实战了。
写到这里不得不吐槽一下,这个金三银四的跳槽季节,年前提离职了,结果离职还没办完就封村整整两个礼拜了,呜呜呜...
上节小二就提到会有个很有意思的小案例,那么在疫情当下,门都出不去的日子,感觉这个例子更有意思了,咱们来讨论一下各种社交平台怎么做的用户信息搜索呢。
社交平台有一个小伙伴们都喜欢的功能,搜索好友信息,比如小二熟练的点开省份...城市..性别..年龄..身高...
咳咳咳...小二怎么可能干这种事情,小二的心里只有代码,嗯...没错,就是这样。
这个就可以说是对于用户信息的查询筛选了,通常这种表都是非常大数据量的,在不考虑分库分表的情况下,怎么通过索引配合SQL来优化呢?
通常我们在编写SQL是会写出类似如下的SQL来执行,有 where、order by、limit 等条件来查询。
那么接下来小二一个一个慢慢增加字段来分析分析,怎么根据业务场景来设计索引。
针对这种情况,很简单,设计一个联合索引 (provice, city, sex) 就完事了。
那么这时候有小伙伴就会说了,很简单啊,范围字段放最后咱还是知道的,联合索引改成 (provice, city, sex, age) 不就可以了。
嗯,是的,这么干没毛病,但是小伙伴们有没有想过有些人万一既喜欢帅哥又喜欢美女,别想歪了哈...,挺多小姐姐就既喜欢帅哥又喜欢美女的。
那么这个时候小姐姐就不搜索性别了,那么这个时候联合索引只能用到前两个字段了,那么不符合咱们的专业标准啊,咋办呢?这时候还是有办法的,咱们只需要动动小脑袋改改SQL就行了,在没有选择性别时判断一下,改成下面这样就可以了。
咋办嘞,同样往联合索引里面塞,例如 (provice, city, sex, hobby, xx, age) 。
针对这种多个范围查询的话,为了比较好的利用索引,在业务允许的情况下可以使用固定范围,然后数据库字段存储范围标识就可以了,这样就转化为了等值匹配,就可以很好地利用索引了。
例如最后登录时间字段不记录最后登录时间,而是记录设置字段 is_login_within_seven_days 在7天内有登录则为1,否则为0,最后索引设计成 (provice, city, sex, hobby, xx, is_login_within_seven_days, age) 。
那么根据场景最后设计出来的这个索引可能已经可以覆盖大部分的查询流量了,那么如果还有其他一部分热度比较高的查询怎么办呢,办法也很简单啊,再加一两个索引即可。
例如通常会查询这个城市比较受欢迎(评分:score)的小姐姐,这时候添加一个联合索引 (provice, city, sex, score) 那么就可以了。
可以看出,索引时必须结合场景来设计的,思路就是尽量用不超过3个复杂的联合索引来抗住大部分的80%以上的常用查询流量,然后再用一两个二级索引来抗下一些非常用查询流量。
以上就是小二要给大家分享的索引设计,如果能动动你发财的小手给小二点个免费的赞就更好啦~
下篇小二就来讲讲MySQL事务和锁机制。