• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 索引提示

    索引提示为优化器提供有关在查询处理期间如何选择索引的信息。此处描述的索引提示与“优化器提示”中描述的优化器提示不同。索引和优化器提示可以单独使用,也可以一起使用。

    索引提示仅适用于SELECTUPDATE语句。

    在表名后指定索引提示。(有关在语句中指定表的一般语法SELECT,请参见“ JOIN子句”。)引用单个表(包括索引提示)的语法如下所示:

    tbl_name [[AS]  lias] [index_hint_list]
    
    index_hint_list:
        index_hint [index_hint] ...
    
    index_hint:
        USE {INDEX|KEY}
          [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
      | {IGNORE|FORCE} {INDEX|KEY}
          [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
    
    index_list:
        index_name [, index_name] ...
    

    该提示告诉MySQL仅使用命名索引之一来查找表中的行。替代语法告诉MySQL不要使用某些特定的索引。如果显示MySQL使用的索引可能不正确,则这些提示很有用。USE INDEX(index_list)IGNORE INDEX(index_list)EXPLAIN

    FORCE INDEX提示的作用就像,增加表扫描被认为是非常昂贵的。换句话说,仅当无法使用命名索引之一在表中查找行时才使用表扫描。USE INDEX(index_list)

    注意

    从MySQL 8.0.20的,服务器支持该索引级优化标记JOIN_INDEXGROUP_INDEXORDER_INDEX,和INDEX,其中等同于和用于替代FORCE INDEX索引提示,以及所述NO_JOIN_INDEXNO_GROUP_INDEXNO_ORDER_INDEX,和NO_INDEX优化标记,这相当于和意图取代IGNORE INDEX索引提示。因此,您应该期望USE INDEXFORCE INDEXIGNORE INDEX在将来的MySQL版本中被弃用,并在之后的某个时间将其完全删除。有关更多信息,请参见索引级优化器提示。

    每个提示都需要索引名称,而不是列名称。要引用主键,请使用名称PRIMARY。要参见表的索引名,请使用SHOW INDEX语句或INFORMATION_SCHEMA.STATISTICS表。

    index_name价值不一定是完整的索引名。它可以是索引名称的明确前缀。如果前缀不明确,则会发生错误。

    例子:

    SELECT * FROM table1 USE INDEX (col1_index,col2_index)
      WHERE col1=1 AND col2=2 AND col3=3;
    
    SELECT * FROM table1 IGNORE INDEX (col3_index)
      WHERE col1=1 AND col2=2 AND col3=3;
    

    索引提示的语法具有以下特征:

    • 它在语法上是有效的,省略index_listUSE INDEX,这手段“不使用索引。”省略index_listFORCE INDEX或者IGNORE INDEX是一个语法错误。
    • 您可以通过FOR在提示中添加一个子句来指定索引提示的范围。这为查询处理的各个阶段提供了对执行计划的优化器选择的更精细控制。要仅影响MySQL决定如何在表中查找行以及如何处理联接时使用的索引,请使用FOR JOIN。要影响索引对行进行排序或分组的用法,请使用FOR ORDER BYFOR GROUP BY
    • 您可以指定多个索引提示:

      SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY  ;
      

      在多个提示中命名同一索引(即使在同一提示中)也不是错误:

      SELECT * FROM t1 USE INDEX (i1) USE INDEX (i1,i1);
      

      但是,它是混合错误USE INDEXFORCE INDEX同一个表:

      SELECT * FROM t1 USE INDEX FOR JOIN (i1) FORCE INDEX FOR JOIN (i2);
      

    如果索引提示不包含任何FOR子句,则提示的范围将应用于语句的所有部分。例如,以下提示:

    IGNORE INDEX (i1)
    

    等效于以下提示组合:

    IGNORE INDEX FOR JOIN (i1)
    IGNORE INDEX FOR ORDER BY (i1)
    IGNORE INDEX FOR GROUP BY (i1)
    

    在MySQL 5.0中,没有FOR子句的提示作用域仅适用于行检索。若要在不存在FOR子句时使服务器使用此较旧的行为,请old在服务器启动时启用系统变量。请注意在复制设置中启用此变量。使用基于语句的二进制日志记录,对主服务器和从服务器使用不同的模式可能会导致复制错误。

    当索引提示进行处理,它们被收集在由类型的单个列表(USEFORCEIGNORE)和范围(FOR JOINFOR ORDER BYFOR GROUP BY)。例如:

    SELECT * FROM t1
      USE INDEX () IGNORE INDEX (i2) USE INDEX (i1) USE INDEX (i2);
    

    等效于:

    SELECT * FROM t1
       USE INDEX (i1,i2) IGNORE INDEX (i2);
    

    然后按以下顺序将索引提示应用于每个范围:

    1. {USE|FORCE}INDEX如果存在,则应用。(如果不是,则使用优化程序确定的索引集。)
    2. IGNORE INDEX应用于上一步的结果。例如,以下两个查询是等效的:

      SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX (i2) USE INDEX (i2);
      
      SELECT * FROM t1 USE INDEX (i1);
      

    对于FULLTEXT搜索,索引提示的工作方式如下:

    • 对于自然语言模式搜索,将无提示地忽略索引提示。例如,IGNORE INDEX(i1)在没有警告的情况下被忽略,并且索引仍在使用。
    • 对于布尔模式搜索,带有FOR ORDER BY或的索引提示将FOR GROUP BY被静默忽略。索引提示带有FOR JOIN或不带有FOR修饰符。与提示如何应用于非FULLTEXT搜索相反,提示用于查询执行的所有阶段(查找行和检索,分组和排序)。即使为非FULLTEXT索引提供了提示,也是如此。

      例如,以下两个查询是等效的:

      SELECT * FROM t
        USE INDEX (index1)
        IGNORE INDEX (index1) FOR ORDER BY
        IGNORE INDEX (index1) FOR GROUP BY
        WHERE ... IN BOOLEAN MODE ... ;
      
      SELECT * FROM t
        USE INDEX (index1)
      WHERE ... IN BOOLEAN MODE ... ;