Mysql创建高性能的索引

 ---------------如果使用ORM框架,是否还需要关心索引-------------

是的,即使使用ORM工具。因为ORM工具通常只能在针对主键查询的时候,生产合法,符合逻辑的查询语句。否则很难生成合适的查询。无论多么复杂的ORM工具,在精妙和复杂的索引面前都是“浮云”。

InnoDB的索引和MyiSAM的区别(https://www.cnblogs.com/olinux/p/5217186.html)

索引的优点:

          1.     索引大大减少了服务器需要扫描的数据量

          2.    索引可以帮助服务器避免排序和临时表。

          3.    索引可以将随机IO变为顺序IO。 

1.     索引的类型:

 1.1.     B-Tree索引

(具体的B-Tree和B+Tree的区别https://blog.csdn.net/pangchengyong0724/article/details/76168576)

实际上很多存储引擎使用的是B+Tree,即每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。通常B-Tree索引意味着所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同。

InnoDB下,B-Tree索引能够提升访问数据的速度,因为存储引擎不再需要进行全表扫描,只需要从索引的根节点开始搜索。根节点的槽中存放了指向子节点的指针,存储引擎可以根据这些指针向下查找,然后通过比较值来获取数据。

叶子结点比较特殊,他们的指针指向的是被索引的数据,而不是其他叶子节点。

                   索引对多个值进行排序的依据就是create table语句中定义索引时的顺序。


 适合使用B-Tree的查询类型:

                   B-Tree索引适用于全键值、键值范围或键前缀查找。其中键前缀只适合用于根据最左前缀查找(MySQL相关特性)。如:(A,B,C)

              全值匹配:

                                指的是和索引中所有的列进行匹配。A and B and C

              匹配最左前缀:

                                 索引的第一列:如A=...

              匹配列前缀:

可以用于查找所有以第一列开头的模糊匹配,比如A%,只是用了第一列。

              匹配范围值:

                                  可以匹配第一列的范围值,比如从Allen和Barrymore之间的人。只是用了第一列。

              精确匹配某一列并范围另外一列:

                                  比如 A and B%

              只访问索引的查询:     

                                  只访问索引,无需访问数据行。

因为索引树中的节点是有序的,所以除了按值查找意外,索引还可以用于查询中的ORDER BY操作(按顺序查找)。所以ORDER BY字句满足前面列出的几种查询类型,则这个索引也可以满足对应的排序需求


              B-Tree索引的限制:

                   1.     如果不是按照索引的最左列开始查找,则无法使用索引。

                   2.     不能跳过索引中的列。比如A and C ,这样只能使用第一列A索引。

                   3.     如果查询中有某个列的范围值,则其右边的所有列无法使用索引优化查找。

  1.2         哈希索引

 哈希索引基于哈希表实现的,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎会对所有的索引列计算一个哈希码。存储在索引中,同时哈希表中保存指向每个数据的指针。MySQL中,只有Memory引擎支持哈希索引。


              哈希索引的限制:

                        1.     哈希索引只包含哈希值和行指针,而不存储字段值,索引不能使用索引中的值来避免读取行。

                        2.     不是按顺序的,所以不能排序。

                        3.     哈希索引也不支持部分索引列匹配查找。如,在(A,B)上建立索引,查询只有列A,无法使用索引。

                        4.     哈希索引只支持比较查询,包括=、IN()、<=>(<>和<=>是不同的操作),也不支持范围查找,如:where price > 100;

                        5.     访问哈希表的速度很快,除非有哈希冲突。


         InnoDB引擎有一个特殊的功能叫做 “自适应哈希索引”。当InnoDB注意到某些索引值被使用的很频繁时,他会在内存中基于B-Tree索引之上在建立一个哈希索引,这就让B-Tree索引也具有了哈希索引的有点,比如快速查找,这是一个完全自动的,内部行为,用户无法控制。




 1.3            空间数据索引 

 MyISAM支持空间索引,可以用做地理数据存储,和B-Tree索引不同,查询时支持任何维度来组合查询。必须使用MySQL的GIS函数如MBRCONTAINS()等来维护数据。但是开源数据库系统对GIS的解决方案做的比较好的是PostgreSQL的PostGIS。       

1.4           全文索引

 全文索引是一种特殊的索引,他不是比较值而是查找文本中的关键词,有许多需要注意的细节,比如停用词,词干和复数,布尔搜索等等。更类似于搜索引擎,不是简单的where语句匹配。 

                   

                 可以再相同的列上同时建立全文索引和基于值的B-Tree索引,不会起冲突,全文搜索适用于Match aganist操作,而不是普通的where条件操作。

 索引的使用注意:

 独立的列:

              如果查询中的列不是独立的,则MySQL就不会使用索引。“独立的列”是指索引列不能是表达式的一部分,也不能是函数的参数。比如;     select actor_id from sakila.actor where actor_id + 1 = 5;

 前缀索引和索引的选择性:

              有时候需要索引很长的字符串,这会使索引变得大且慢,一种办法就是模拟哈希索引,通常还可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率。但是也会降低索引的选择性。索引的选择性是指,不重复的索引值(也称为基数)和数据表的记录总数(#T)的比值,范围从1/#T 到 1之间。选择性越高越好,因为选择性高的索引可以让MySQL在查找时过滤掉更多的行,选择行是1的时候,是最好的索引选择性,性能也是最好的

 使前缀的选择性接近于完整列的选择性。

              select count(distinct city)/count(*) from sakila.city_demo.

              创建前缀索引:

              alter table  sakila.city_demo  add key(city(7));

前缀索引无法使用order by 和 group by。

 多列索引:

              在多个列上建立独立的单列索引大部分情况下并不能提高MySQL的查询性能。MySQL5.0和更新版本引入了一种叫“索引合并”的策略。

              select film_id, actor_id from sakila.film_actor where actor_id = 1 or film_id =1;在老的MySQL版本中,MySQL对这个查询会使用全表扫描。除非改写成UNION的方式:

select film_id, actor_id from sakila.film_actor where actor_id = 1

              UNION ALL

select film_id, actor_id from sakila.film_actor where film_id = 1 and actor_id <> 1;


             MySQL5.0和更新的版本中,查询能够同时使用这两个单列索引进行扫描,并将结果合并。


当服务器需要对多个索引做联合操作时(通常有多个OR条件),通常需要耗费大量CPU和内存资源在算法的缓存,排序和合并上。特别是当有些索引的选择性不高,需要合并扫描返回大量数据的时候。

    

    选则合适的索引顺序:

 适用于B-Tree索引。对于如何选择列的顺序有一个经验法则:将选择性最高的列放到索引最前列。但是如果索引的选择性太低,再好的索引也很难起到作用。尽可能的将范围查询的列放到索引的后面,以便优化器使用更多的索引列。

总结:

          1.     单行数据访问是很慢的。特别是在机械硬盘存储中,使用索引创建位置引用以提升效率。

             2.    按顺序访问范围数据是很快的。第一,顺序IO不需要多次磁盘寻道,所以比随机IO要快很多。第二,如果服务器能够按照顺序读取数据,就不需要额外的排序操作。

             3.     索引覆盖查询时很快的。

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

推荐阅读更多精彩内容