索引的三星原则

1.索引将相关的记录放到一起,则获得一星

2.如果索引中的数据顺序和查找中的排列顺序一致则获得二星

3.如果索引中的列包含了查询中的需要的全部列则获得三星

多列索引

1.1、多个单列索引

  很多人对多列索引的理解都不够。一个常见的错误就是,为每个列建立独立的索引,或者按照错误的顺序创建多列索引。

  我们会在稍后的章节中单独讨论索引列的顺序问题。先来看第一个问题,为每个列创建独立的索引,从SHOW CREATE TABLE 中很容易看到这种情况:

CREATE TABLE t(
 c1 INT,c2 INT , c3 INT ,KEY(c1),KEY(c2),KEY(c3)
);

  这种索引策略,一般是由于人们听到一些专家诸如“把WHERE 条件里面的列都建上索引”这样模糊的建议导致的。实际上这个建议是非常错误的。这样一来最好的情况也只能是“一星”索引,其性能比起真正最有效的索引可能差几个数量级。有时如果无法设计出一个“三星”索引,那么不如忽略掉WHERE 子句,集中精力优化索引列的顺序,或者创建一个全覆盖索引。

索引合并

  在多个列上建立独立的单列索引大部分情况下不能提高MySQL的查询性能。MySQL5.0和更高的版本医用了一种叫“索引合并”策略,一定程度上可以使用表上的多个单列索引来定位指定的行。更早版本的MySQL只能使用其中某一个单列索引,然而这种情况下没有哪一个独立索引是非常有效的。例如在film_actor在字段film_id和actor_id上各有一个单列索引。但是对于这个查询WHERE 条件,这两个单列索引都不是好的选择:

SELECT film_id ,actor_id FROM film_actor WHERE actor_id=1 or film_id =1;

  在老的MySQL版本中,MySQL对于这个查询是会使用全表扫描的,除非改写成如下的两个查询UNION的方式:

SELECT film_id ,actor_id FROM film_actor WHERE actor_id=1
  UNION ALL
  SELECT film_id ,actor_id FROM film_actor WHERE film_id=1;

但是在MySQL5.0 和更高的版本中,查询能够同时使用者两个单列索引进行扫扫描,并将结果进行合并。这种算法有三个变种:OR条件的联合(union),AND条件的相交(intersection),组合前面两种情况的联合及相交。下面的查询就是使用了两个索引扫描的联合,通过EXPLAIN中的Extra列可以看出这点:

EXPLAIN SELECT film_id,actor_id FROM film_actor WHERE actor_id=1 or film_id = 1 \G

 

MySQL会使用这类技术优化负责的查询,所以在某些语句的EXTRA列中还可以看到嵌套操作。

  索引合并策略有时候是一种优化的结构,但实际上更多的时候说明了表上的索引建的很糟糕

  当出现服务器对多个索引做相交操作(通常有多个AND条件),通常意味着需要一个包含所有相关列的多个索引,而不是独立的单列索引。

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

  更重要的是,优化器不会吧这些成本算到“查询成本”中,游虎丘只关心随机页面读取。这会使得查询成本被低估,导致该执行计划还不如直接走全表扫描。这样做不但会消耗更多的cup和内存资源,还可能影响查询的并发性,但如果是单独鱼腥这样的查询则往往会忽略对并发现的影响。通常来说,还不弱在MySQL4.1或更早的时代一样,将查询改写成UNION的方式往往会更好。

如果在Explain语句中看到索引合并,应该好好检查一下查询和表的结构。也可以通过参数optimizer_switch来关闭索引合并功能。也可以使用IGNORE_INDEX提示让优化器忽略掉某些索引。

==========================================================================================

为了提高搜索效率,我们需要考虑运用多列mysql数据库索引。如果为firstname、lastname和age这三个列创建一个多列索引,MySQL只需一次检索就能够找出正确的结果!下面是创建这个复合索引的SQL命令:

ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age); 

由于索引文件以B-树格式保存,MySQL能够立即转到合适的firstname,然后再转到合适的lastname,最后转到合适的age。在没有扫描数据文件任何一个记录的情况下,MySQL就正确地找出了搜索的目标记录!

那么,如果在firstname、lastname、age这三个列上分别创建单列索引,效果是否和创建一个firstname、lastname、age的多列MySQL数据库索引一样呢?答案是否定的,两者完全不同。当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的MySQL数据库索引,MySQL会试图选择一个限制最严格的索引。

但是,即使是限制最严格的单列索引,它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列索引。

索引是快速搜索的关键。MySQL索引的建立对于MySQL的高效运行是很重要的。

1.2、复合索引

联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c)。 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。两个或更多个列上的索引被称作复合索引。

见《mysql索引之四:复合索引之最左前缀原理,索引选择性,索引优化策略之前缀索引

 

mysql索引之五:多列索引的更多相关文章

  1. 正确理解Mysql的列索引和多列索引

    MySQL数据库提供两种类型的索引,如果没正确设置,索引的利用效率会大打折扣却完全不知问题出在这. CREATE TABLE test ( id         INT NOT NULL, last_ ...

  2. mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)

    没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...

  3. 认识SQLServer索引以及单列索引和多列索引的不同

     一.索引的概念 索引的用途:我们对数据查询及处理速度已成为衡量应用系统成败的标准,而采用索引来加快数据处理速度通常是最普遍采用的优化方法. 索引是什么:数据库中的索引类似于一本书的目录,在一本书中使 ...

  4. Atitit.  单列索引与多列索引 多个条件的查询原理与设计实现

    Atitit.  单列索引与多列索引 多个条件的查询原理与设计实现 1. MySQL只能使用一个索引1 1.1. 最左前缀1 1.2. 从另一方面理解,它相当于我们创建了(firstname,last ...

  5. Mysql的列索引和多列索引(联合索引)

    转自:http://blog.chinaunix.net/uid-29305839-id-4257512.html 创建一个多列索引:CREATE TABLE test (      id       ...

  6. MySQL Index--关联条件列索引缺失导致执行计划性能不佳

    某系统反馈慢SQL影响生产,查看SLOW LOG发现下面慢SQL: SELECT COUNT(DISTINCT m.batch_no) FROM ob_relation r INNER JOIN ob ...

  7. MySQL 最左前缀(Leftmost Prefix) & 组合索引(复合索引,多列索引)

    资料来源于网络,仅供参考学习. CREATE TABLE test(a INT,b INT,c INT,KEY idx(a,b,c)); 优: SELECT * FROM test WHERE a=1 ...

  8. mysql多列索引和最左前缀

    数据库的索引可以加快查询速度,原因是索引使用特定的数据结构(B-Tree)对特定的列额外组织存放,加快存储引擎(索引是存储引擎实现)查找记录的速度.索引优化是数据库优化的最重要手段. 如果查询语句使用 ...

  9. mysql索引之四(索引使用注意规则:索引失效--存在索引但不使用索引)

    但是如果是同样的sql如果在之前能够使用到索引,那么现在使用不到索引,以下几种主要情况: 1. 随着表的增长,where条件出来的数据太多,大于15%,使得索引失效(会导致CBO计算走索引花费大于走全 ...

  10. mysql索引之三:索引使用注意规则(索引失效--存在索引但不使用索引)*

    使用索引时,有以下一些技巧和注意事项: (1)越小的数据类型通常更好:越小的数据类型通常在磁盘.内存和CPU缓存中都需要更少的空间,处理起来更快.(2)简单的数据类型更好:整型数据比起字符,处理开销更 ...

随机推荐

  1. New Concept English three(16)

    35w/m 43 Mary and her husband Dimitri lived in the tiny village of Perachora in southern Greece. One ...

  2. Windows环境下redis 配置文件中设置的密码无效

    当我们安装了redis服务后,发现在其配置文件redis.windows.conf(或redis.conf)设置了密码:requirepass ****** 但是打开redis-cli.exe后输入命 ...

  3. [置顶] Deep Learning 资料库

    一.文章来由 网络好文章太多,而通过转载文章做资料库太麻烦,直接更新这个博文. 二.汇总 1.台大李宏毅老师的课 正片:http://speech.ee.ntu.edu.tw/~tlkagk/cour ...

  4. weight decay (权值衰减)

    http://blog.sina.com.cn/s/blog_890c6aa30100z7su.html 在机器学习或者模式识别中,会出现overfitting,而当网络逐渐overfitting时网 ...

  5. php 配置上传大文件

    打开php.ini,首先找到file_uploads = on ;是否允许通过HTTP上传文件的开关.默认为ON即是开upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就 ...

  6. ubuntu16.04 LTS grafana安装与启动

    1.首先从官网上下载相应的包,网址为:http://grafana.org/download 2.安装 cd Downloads sudo dpkg -i grafana_4.1.2-14869897 ...

  7. sync or async connect redis in golang

    Head of head 在golang的整个生态里,redis client lib全部都使用多连接或者连接池.这是让人难以理解的,所以我和xiaofei一起写了一个同时支持同步和异步的redis ...

  8. BZOJ3994:约数个数和(莫比乌斯反演:求[1,N]*[1,M]的矩阵的因子个数)

    Description  设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Outpu ...

  9. NOI2001 食物链【扩展域并查集】*

    NOI2001 食物链 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的 ...

  10. BZOJ1066 SCOI2007 蜥蜴 【网络流-最大流】

    BZOJ1066 SCOI2007 蜥蜴 Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离 ...