美文网首页数据库
mysql--索引优化

mysql--索引优化

作者: 机智的老刘明同志 | 来源:发表于2018-10-04 12:28 被阅读16次

    索引覆盖:

            索引覆盖是指如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据。这种查询速度非常快,称为”索引覆盖”

    理想中的索引:

            1:查询频繁 2:区分度高  3:长度小  4: 尽量能覆盖常用查询字段

    索引长度与区分度的均衡:

            索引长度直接影响索引文件的大小,影响增删改的速度,并间接影响查询速度(占用内存多)

            因此对于一些长短不同的字节,我们会针对列中的值,从左往右截取部分,来建索引。但是:

            1:截的越短, 重复度越高,区分度越小, 索引效果越不好

            2:截的越长, 重复度越低,区分度越高, 索引效果越好,但带来的影响也越大--增删改变慢,并间影响查询速度.

            所以,我们要在  区分度 + 长度  两者上,取得一个平衡

            select count (distinct left (word,6)) / count (*) from tablename;

            对于一般的系统应用:区别度能达到0.1,索引的性能就可以接受.

            alter table tablename add index word(word(4));

    伪hash索引(crc32):

            给字符串类型的字段建立索引效率不高,但是必须要经常查这个字段怎么建索引?比如这个字段名称是url字符串类型,那么可以建一个字段 crcurl 来存储 url字段crc32后的值,并给这个字段建立索引。

            crc32 是整形,在MySQL中,给整形字段建立索引效率比较高,crc32虽然不能确保唯一性,但是无碍,相同的机率也是极小,关键是可以大大减少查询的范围,给crcurl这个字段建立索引,查询的时候带上crcurl字段就可以利用到索引。

    大数据量分页优化:

            1:从业务上去解决

                办法:不允许翻过100页

                以百度为例,一般翻页到70页左右.

            
            2:不用offset,用条件查询

            首先我们直接大数据分页limit 5000000,10  发现耗时4.41秒

            接下来我们转换方式使用where条件查询,只耗时0.02秒

                但是问题来了: 2次的查询结果不一致

                原因:数据被物理删除过,有空洞.

                解决:数据不进行物理删除(可以逻辑删除).

                最终在页面上显示数据时,逻辑删除的条目不显示即可.

                (一般来说,大网站的数据都是不物理删除的,只做逻辑删除 ,比如 is_delete=1)

            3:非要物理删除,还要用offset精确查询,还不限制用户分页,怎么办?延迟关联

                分析:优化思路是 不查,少查,查索引,少取.

                我们现在必须要查,则只查索引,不查数据,得到id.

                再用id去查具体条目.  这种技巧就是延迟索引.

            分析:limit是先查询再越过,也就是说我们先查询出所有数据再进行跳跃,上图我们越过500W页,还使用了inner join  内存并没有崩掉,这是因为我们子句tmp临时表中只查询了id(索引覆盖,不需要回行去磁盘找数据了)然后拿到这10个id 分别查询这10条数据 。

    索引与排序:

            排序可能发生2种情况:

            1:对于覆盖索引,直接在索引上查询时,就是有顺序的, using index

            2:先取出数据,形成临时表做filesort(文件排序,但文件可能在磁盘上,也可能在内存中)

            我们的争取目标-----取出来的数据本身就是有序的! 利用索引来排序.

            比如: goods商品表, (cat_id,shop_price)组成联合索引,

            where cat_id=N order by shop_price ,可以利用索引来排序,

            select goods_id,cat_id,shop_price from goods order by shop_price;

            // using where,按照shop_price索引取出的结果,本身就是有序的.

    using where

             select goods_id,cat_id,shop_price from goods order by click_count;

            // using filesort用到了文件排序,即取出的结果再次排序

     using filesort

    重复索引与冗余索引

            重复索引是指 在同1个列(如age), 或者顺序相同的几个列(age,school), 建立了多个索引,称为重复索引,重复索引没有任何帮助,只会增大索引文件,拖慢更新速度。

            冗余索引是指2个索引所覆盖的列有重叠, 称为冗余索引。比如x,m,列,加索引 index x(x),  index xm(x,m) x,xm索引, 两者的x列重叠了,  这种情况,称为冗余索引. (mx, xm 不是重复的,因为列的顺序不一样)

    相关文章

      网友评论

        本文标题:mysql--索引优化

        本文链接:https://www.haomeiwen.com/subject/khktaftx.html