5.3高性能的索引策略《创建高性能的索引》(3.4.5未完待续)

先概括一下索引的策略: 

1)单列索引 

2)前缀索引 

3)多列索引 

4)选择合适索引顺序

5)聚簇索引 

6)覆盖索引

7)索引扫描进行排序

8)压缩索引

9)冗余和重复索引

11)索引和锁

一、单列索引

索引列必须独立,即不能是表达式或函数的一部分

无法正却使用索引:select actor_id from actor where actor_id+1=5;

select ... where TO_DAYS(CURRENT_DATE) - TO_DAYS(date_col)<=10;

二、前缀索引

索引的列很长,导致索引大且慢,只索引列开始的部分(某一列的前面几个字符),节省空间也加快速度,但降低索引的选择性(查出结果变多)。

alter tabel XXX add key (col(7)) 前7位索引

通过left前几位计算相应长度的选择性,越大越好

缺点:mysql无法使用前缀索引做GROUP BY和ORDER BY,也无法使用前缀索引做覆盖扫描。

六、覆盖索引

索引包含(或说覆盖)所有需要查询的字段的值,为覆盖索引。

只需扫描索引就能在索引的叶子节点中获得所有的数据,不需回表查询,提高性能。好处:

(1)减少数据访问量(索引条目通常小于数据行的大小),缓存的负载重要。

(2)IO密集型的范围查找会比随机从磁盘中读取每一行数据的IO要少得多、因为索引是按照列值顺序存储

例1:索引覆盖的查询时,在EXPLAIN的Extra列可以看到Usingi ndex的信息。  

例2:索引无法覆盖该查询,有两个原因:

(1)查询所有的列,没有任何索引覆盖了所有的列。

(2)MySQL不能在索引中执行LIKE操作。

例3:解决办法:延迟关联

查询中找到匹配的prod_id

例4:InnoDB的二级索引叶子节点:包含了主键的值,可有效地利用这些“额外“主键来覆盖查询。

sakila.actor使用InnoDB存储引擎,并在last_name字段有二级索引,索引不包含主键actor_id,也能覆盖查询:

七、索引扫描进行排序

EXPLAIN出来的type列的值为“index“,则说明MySQL使用索引扫描来做排序(不要和Extra列的“Using index”搞混淆了)

(1)索引列顺序与order by子句顺序完全一致:顺/逆序,满足最左前缀要求

(2)关联多张表order by字段必须是第一张表

没满足最左前缀要求

改进:WHERE rental_date = ‘2005-05-25’ ORDER BY inventory_id DESC;   使用第二列进行排序,将两列组合在一起

           WHERE rental_date > ‘2005-05-25’ ORDER BY rental_date, inventory_id;

错误:

排序不同:WHERE rental_date = ‘2005-05-25’ ORDER BY inventory_id DESC , customer_id ASC;

引用不在索引中的列:WHERE rental_date = ‘2005-05-25’ ORDER BY inventory_id , staff_id;

无法组合成索引的最左前缀: WHERE rental_date = ‘2005-05-25’ ORDER BY customer_id;

范围条件无法使用索引的其余列:WHERE rental_date = ‘2005-05-25’ ORDER BY inventory_id , customer_id;

                                                          WHERE rental_date = ‘2005-05-25’ AND inventory_id IN(1,2) ORDER BY customer_id;

关联的第二张表:

八、压缩索引

虽然节省空间,但遍历花很多时间

方法:完全保存一个值,其他值和第一个值进行比较得不同后缀部分,例:第一个“perform“,第二个”performance“,”7,ance“这样的形式。

无法二分查找,只能从头开始。正序扫描速度还不错,倒序ORDER BY DESC不好

适用I/O密集型应用;对于CPU密集型更慢(压缩索引需要在CPU内存资源与磁盘之间做权衡

CREATE TABLE语句中指定PACK_KEYS参数来控制索引压缩的方式。

九、冗余和重复索引

相同列上创建多个索引,影响性能。三个重复的索引:

CREATE TABLE test(

    ID INT NOT NULL PRIMARY KEY, //主键限制

    A INT NOT NULL,

    B INT NOT NULL,

    UNIQUE(ID),  //唯一限制

    INDEX(ID) //索引

) ENGINE=InnoDB;

1.冗余索引:(1)索引(A,B),再创建索引(A)就是

                  (2)(A,ID),ID是主键,因为InnoDB来说主键列已经包含在二级索引中

2.不是冗余索引:创建索引(B,A),索引(B)也不是,不是索引(A,B)的最左前缀。或不同类型的索引

3.例:userinfo表。1000000行,每个state_id值大概有20000条记录。state_id列有一个索引对下面的查询有用:

Q1:SELECT count(*) FROM userinfo WHERE state_Id=5;  115次(QPS)

Q2SELECT state_id,city,address FROM userinfo WHERE state_id=5;  QPS小于10

扩展索引为(state_id,city,address),覆盖查询:

ALTER TABLE userinfo DROP KEY state_id, ADD KEY state_id_2(state_id,city,address);

Q2得更快了,Q1却变慢了

4.大多数情况下不需要冗余索引,删除掉,尽量扩展不是创建新索引,增加新索引将会导致INSERT、UPDATE、DELETE等操作的速度变慢

十一、索引和锁

锁定超过需要的行会增加锁争用减少并发性

InnoDB只访问行才加锁

获取了1~4之间的行的排他锁。InnoDB锁住第1行

EXPLAIN的Extra列出现了”Using where“,表示MySQL服务器将存储引擎返回行以后再应用WHERE过滤条件

这个查询挂起,直到释放第1行的锁

InnoDB、索引和锁有一些很少有人知道的细节:InnoDB在二级索引上使用共享(读)锁,但访问主键索引需要排他(写)锁。消除了使用覆盖索引的可能性,使SELECT FOR UPDATELOCK IN SHARE MODE非锁定查询要慢得多。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353