• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 多列索引

    MySQL可以创建复合索引(即,多列上的索引)。一个索引最多可以包含16列。对于某些数据类型,您可以为列的前缀建立索引(请参见“列索引”)。

    MySQL可以将多列索引用于测试索引中所有列的查询,或仅测试第一列,前两列,前三列等等的查询。如果在索引定义中以正确的顺序指定列,则单个复合索引可以加快对同一表的几种查询。

    多列索引可以被认为是排序数组,其行包含通过串联索引列的值而创建的值。

    注意

    作为复合索引的替代方法,您可以根据其他列中的信息引入一个被“哈希化”的列。如果此列较短,合理唯一并且已建立索引,则它可能比许多列上的“宽”索引更快。在MySQL中,使用此额外的列非常容易:

    SELECT * FROM tbl_name
      WHERE hash_col=MD5(CONCAT(val1,val2))
      AND col1=val1 AND col2=val2;
    

    假设一个表具有以下规范:

    CREATE TABLE test (
        id         INT NOT NULL,
        last_name  CHAR(30) NOT NULL,
        first_name CHAR(30) NOT NULL,
        PRIMARY KEY (id),
        INDEX name (last_name,first_name)
    );
    

    name指数是在一个索引last_namefirst_name列。该索引可用于查询中的查找,这些查询指定在已知范围内的last_namefirst_name值组合的值。它也可用于仅指定last_name值的查询,因为该列是索引的最左前缀(如本节稍后所述)。因此,该name索引用于以下查询中的查找:

    SELECT * FROM test WHERE last_name='Jones';
    
    SELECT * FROM test
      WHERE last_name='Jones' AND first_name='John';
    
    SELECT * FROM test
      WHERE last_name='Jones'
      AND (first_name='John' OR first_name='Jon');
    
    SELECT * FROM test
      WHERE last_name='Jones'
      AND first_name >='M' AND first_name < 'N';
    

    但是,在以下查询中,name索引用于查找:

    SELECT * FROM test WHERE first_name='John';
    
    SELECT * FROM test
      WHERE last_name='Jones' OR first_name='John';
    

    假设您发出以下SELECT语句:

    SELECT * FROM tbl_name
      WHERE col1=val1 AND col2=val2;
    

    如果col1和上存在多列索引col2,则可以直接获取相应的行。如果col1和上存在单独的单列索引col2,那么优化器将尝试使用索引合并优化(请参见“优化索引”),或者尝试通过确定哪个索引排除更多行并使用来查找限制性最强的索引。该索引以获取行。

    如果表具有多列索引,那么优化器可以使用索引的任何最左前缀来查找行。举例来说,如果你有一个三列的索引(col1, col2, col3),你有索引的搜索功能(col1)(col1, col2)以及(col1, col2, col3)

    如果列未形成索引的最左前缀,则MySQL无法使用索引执行查找。假设您具有以下SELECT所示的语句:

    SELECT * FROM tbl_name WHERE col1=val1;
    SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
    
    SELECT * FROM tbl_name WHERE col2=val2;
    SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;
    

    如果存在一个索引(col1, col2, col3),则仅前两个查询使用该索引。第三和第四查询的确包含索引列,但不使用索引来执行查找,因为(col2)(col2, col3)它们不是的最左前缀(col1, col2, col3)