`

MySQL使用单列索引和多列索引

阅读更多

讨论MySQL选择索引时单列单列索引和多列索引使用,以及多列索引的最左前缀原则。

1. 单列索引

    在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一。可以考虑使用索引的主要有两种类型的列:在Where子句中出现的列,在join子句中出现的列。请看下面这个查询: 

Select age ## 不使用索引 
FROM people Where firstname='Mike' ## 考虑使用索引 
AND lastname='Sullivan' ## 考虑使用索引

    这个查询与前面的查询略有不同,但仍属于简单查询。由于age是在Select部分被引用,MySQL不会用它来限制列选择操作。因此,对于这个查询来说,创建age列的索引没有什么必要。

下面是一个更复杂的例子: 

Select people.age, ##不使用索引 
town.name ##不使用索引 
FROM people LEFT JOIN town ON people.townid=town.townid ##考虑使用索引 
Where firstname='Mike' ##考虑使用索引 
AND lastname='Sullivan' ##考虑使用索引

    与前面的例子一样,由于firstname和lastname出现在Where子句中,因此这两个列仍旧有创建索引的必要。除此之外,由于town表的townid列出现在join子句中,因此我们需要考虑创建该列的索引。 

    那么,我们是否可以简单地认为应该索引Where子句和join子句中出现的每一个列呢?差不多如此,但并不完全。我们还必须考虑到对列进行比较的操作符类型。MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。

可以在LIKE操作中使用索引的情形是指另一个操作数不是以通配符(%或者_)开头的情形。

例如:

Select peopleid FROM people Where firstname LIKE 'Mich%'

这个查询将使用索引;但下面这个查询不会使用索引。 

Select peopleid FROM people Where firstname LIKE '%ike';

2. 多列索引

    索引可以是单列索引,也可以是多列索引。下面我们通过具体的例子来说明这两种索引的区别。假设有这样一个people表: 

 

Create TABLE people ( 
peopleid SMALLINT NOT NULL AUTO_INCREMENT, 
firstname CHAR(50) NOT NULL, 
lastname CHAR(50) NOT NULL, 
age SMALLINT NOT NULL, 
townid SMALLINT NOT NULL, 
PRIMARY KEY (peopleid) );

    下面是我们插入到这个people表的数据:  

    这个数据片段中有四个名字为“Mikes”的人(其中两个姓Sullivans,两个姓McConnells),有两个年龄为17岁的人,还有一个名字与众不同的Joe Smith。 

    这个表的主要用途是根据指定的用户姓、名以及年龄返回相应的peopleid。例如,我们可能需要查找姓名为Mike Sullivan、年龄17岁用户的peopleid: 

Select peopleid
FROM people 
Where firstname='Mike' 
      AND lastname='Sullivan' AND age=17;

    由于我们不想让MySQL每次执行查询就去扫描整个表,这里需要考虑运用索引。  

    首先,我们可以考虑在单个列上创建索引,比如firstname、lastname或者age列。如果我们创建firstname列的索引(Alter TABLE people ADD INDEX firstname (firstname);),MySQL将通过这个索引迅速把搜索范围限制到那些firstname='Mike'的记录,然后再在这个“中间结果集”上进行其他条件的搜索:它首先排除那些lastname不等于“Sullivan”的记录,然后排除那些age不等于17的记录。当记录满足所有搜索条件之后,MySQL就返回最终的搜索结果。 

    由于建立了firstname列的索引,与执行表的完全扫描相比,MySQL的效率提高了很多,但我们要求MySQL扫描的记录数量仍旧远远超过了实际所需要的。虽然我们可以删除firstname列上的索引,再创建lastname或者age列的索引,但总地看来,不论在哪个列上创建索引搜索效率仍旧相似。 

    为了提高搜索效率,我们需要考虑运用多列索引。如果为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会试图选择一个限制最严格的索引。但是,即使是限制最严格的单列索引,它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列索引。  

3. 多列索引中最左前缀(Leftmost Prefixing) 

    多列索引还有另外一个优点,它通过称为最左前缀(Leftmost Prefixing)的概念体现出来。继续考虑前面的例子,现在我们有一个firstname、lastname、age列上的多列索引,我们称这个索引为fname_lname_age。当搜索条件是以下各种列的组合时,MySQL将使用fname_lname_age索引: 

firstname,lastname,age

firstname,lastname

firstname

    从另一方面理解,它相当于我们创建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)这些列组合上的索引。下面这些查询都能够使用这个fname_lname_age索引:  

Select peopleid FROM people 
Where firstname='Mike' AND lastname='Sullivan' AND age='17'; 
Select peopleid FROM people 
Where firstname='Mike' AND lastname='Sullivan'; 
Select peopleid FROM people 
Where firstname='Mike'; 

下面这些查询不能够使用这个fname_lname_age索引: 

Select peopleid FROM people 
Where lastname='Sullivan'; 

 

Select peopleid FROM people 
Where age='17'; 

 

Select peopleid FROM people 
Where lastname='Sullivan' AND age='17'; 
分享到:
评论
4 楼 waitgod 2016-05-19  
3 楼 greatwqs 2013-08-02  
MySQL索引使用方法和性能优化

http://imfei.blog.51cto.com/1849649/511689
2 楼 greatwqs 2013-08-02  
聚集索引和非聚集索引(整理)

http://www.cnblogs.com/aspnethot/articles/1504082.html
1 楼 greatwqs 2013-08-02  

相关推荐

    MySQL索引使用说明(单列索引和多列索引)

    本文将深入探讨单列索引和多列索引的使用,并介绍多列索引中的最左前缀原则。 1. 单列索引 单列索引,顾名思义,是在单个列上创建的索引。创建索引的主要目的是优化WHERE子句和JOIN子句中的列。例如,如果一个查询...

    mysql多条件索引

    然而,多列索引的使用有其特定规则,被称为“最左前缀原则”。这意味着查询条件必须从索引的第一列开始,并按照索引列的顺序匹配,直到遇到范围查询(如`, `LIKE`等)或者中间缺失某列。例如,对于`name, age, id`的...

    MySql索引详解,索引可以大大提高MySql的检索速度

    单列索引,即一个索引只包合单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。 创建索引时,你需要确保该索引是应用在SQL查询语的条件(一般作为WHERE 子句的条件)实际上,索引...

    MySQL索引分析和优化.pdf

    5. **单列索引与多列索引**:索引可以针对单个列创建(单列索引),也可以针对多个列同时创建(多列索引)。 - **单列索引**:只基于表中的一个列创建索引。 - **多列索引**:基于表中两个或更多列的组合创建索引...

    MySQL索引类型大汇总

    在 MySQL 中,索引可以分为单列索引和组合索引两种。 1. 普通索引 普通索引是最基本的索引类型,没有任何限制。可以通过以下三种方式创建普通索引: * 创建索引:`CREATE INDEX indexName ON mytable(username...

    mysql的索引优化

    1. **单列索引与多列索引**:索引可以是针对单个列的,也可以是多个列的组合。多列索引是指基于两个或多个列创建的索引,适用于查询条件中包含多个字段的情况。 2. **索引优化**:合理选择索引类型和设计索引方案...

    正确理解Mysql中的列索引和多列索引

    总结来说,正确理解和使用MySQL中的列索引和多列索引对于优化数据库性能至关重要。在设计索引时,应考虑到查询模式、数据分布以及索引的存储和维护成本。通过适当选择索引类型和列顺序,可以有效提升查询效率,减少...

    MySQL-数据库-索引详解

    MySQL 索引包括普通索引、惟一性索引、全文索引、单列索引、多列索引和空间索引。 #### 普通索引 创建普通索引时,不附加任何限制条件。可以创建在任何数据类型上,其值是否唯一和非空由字段自身的完整性约束条件...

    MySQL索引分析和优化[定义].pdf

    5. **单列索引**和**多列索引**的区别在于索引覆盖的列数。单列索引只针对一列,而多列索引可以包括两列或更多列。多列索引有助于优化涉及多个列的查询,因为数据库系统可以同时考虑多个列的索引结构。例如,对于一...

    MySQL索引分析和优化

    比如,`people`表中,可以为`firstname`、`lastname`和`age`创建单列索引,但它们的效果与创建一个包含这三个列的多列索引(如`fname_lname_age`)并不相同。多列索引的优势在于,即使只使用其中部分列进行查询,...

    mysql索引与视图的实例附答案宣贯.pdf

    MySQL 中的索引可以分为普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等几种类型。 索引的设计原则包括: 1. 选择唯一性索引; 2. 为经常需要排序、分组和联合操作的字段建立索引; 3. 为常作为...

    MYSQL索引知识

    - **单列索引**:包括普通索引、唯一索引和主键索引。 - 普通索引:无特殊限制,允许重复和空值。 - 唯一索引:索引列值必须唯一,允许空值。 - 主键索引:特殊的唯一索引,不允许空值。 - **组合索引**:...

    MYSQL索引和优化详细说明教程

    单列索引针对单一列进行索引,而多列索引,如在people表中对firstname、lastname和age三列创建的fname_lname_age索引,允许更复杂的查询优化。多列索引的优势在于可以根据多个列的值进行排序和过滤,但需要注意的是...

    MYSQL学习笔记-索引[文].pdf

    * 单列索引和组合索引的选择取决于查询的频率和方式。 四、索引的创建和删除 * 创建索引可以使用CREATE INDEX语句、ALTER语句或CREATE TABLE语句。 * 删除索引可以使用DROP INDEX语句。 五、索引的应用场景 * 在...

    MySQL索引分析及优化.pdf

    单列索引即一个索引只包含单个列,而组合索引即一个索引包含多个列。 四、索引的类型 索引可以分为普通索引、唯一索引、主键索引和全文索引四种。普通索引是最基本的索引,它没有任何限制。唯一索引保证了每个索引...

    mysql索引分析和优化

    5. **单列索引与多列索引**:单列索引基于表中的单个列创建,而多列索引则基于多个列。多列索引在复合查询条件下能提供更高效的检索。 #### 索引优化策略 - **合理选择索引列**:应选择查询中经常用作条件过滤的列...

    mysql实验报告+-+索引的创建与管理

    实验的目的是理解和熟练掌握索引的创建、管理和维护,包括单列索引、多列索引、唯一性索引以及全文索引的使用。通过这些操作,可以提高数据库查询的效率,优化数据访问性能。同时,了解不同存储引擎对索引的支持情况...

Global site tag (gtag.js) - Google Analytics