MySQL:索引的类型及相关优化

一、索引类型

MySQL的索引类型分为两种:BTREE和HASH。在创建索引时可以为其指定任意一种索引类型。其中索引有如下几种:

  • 单列索引
    • 普通索引index :加速查找
  • 唯一索引
    • 主键索引:primary key :加速查找+约束(不为空且唯一)
    • 唯一索引:unique:加速查找+约束 (唯一)
  • 联合索引
    • primary key(id,name):联合主键索引
    • unique(id,name):联合唯一索引
    • index(id,name):联合普通索引
  • 全文索引fulltext :用于搜索很长一篇文章的时候,效果最好。
  • 空间索引spatial

关于BTREE索引可以参考这篇文章:MySQL的InnoDB索引原理详解

二、DDL

MySQL创建索引的语法:

CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name
    [index_type]
    ON tbl_name (key_part,...)
    [index_option]
    [algorithm_option | lock_option] ...

其中各个部分的解释:

  • key_part:

    col_name [(length)] [ASC | DESC]
  • index_option:

    KEY_BLOCK_SIZE [=] value
    | index_type
    | WITH PARSER parser_name
    | COMMENT 'string'
    • Table 13.2 InnoDB Storage Engine Index Characteristics

      Index ClassIndex TypeStores NULL VALUESPermits Multiple NULL ValuesIS NULL Scan TypeIS NOT NULL Scan Type
      Primary keyBTREENoNoN/AN/A
      UniqueBTREEYesYesIndexIndex
      KeyBTREEYesYesIndexIndex
      FULLTEXTN/AYesYesTableTable
      SPATIALN/ANoNoN/AN/A
    • Table 13.3 MyISAM Storage Engine Index Characteristics

      Index ClassIndex TypeStores NULL VALUESPermits Multiple NULL ValuesIS NULL Scan TypeIS NOT NULL Scan Type
      Primary keyBTREENoNoN/AN/A
      UniqueBTREEYesYesIndexIndex
      KeyBTREEYesYesIndexIndex
      FULLTEXTN/AYesYesTableTable
      SPATIALN/ANoNoN/AN/A
    • Table 13.4 MEMORY Storage Engine Index Characteristics

      Index ClassIndex TypeStores NULL VALUESPermits Multiple NULL ValuesIS NULL Scan TypeIS NOT NULL Scan Type
      Primary keyBTREENoNoN/AN/A
      UniqueBTREEYesYesIndexIndex
      KeyBTREEYesYesIndexIndex
      Primary keyHASHNoNoN/AN/A
      UniqueHASHYesYesIndexIndex
      KeyHASHYesYesIndexIndex
  • index_type:

    USING {BTREE | HASH}
    Storage EnginePermissible Index Types
    InnoDBBTREE
    MyISAMBTREE
    MEMORY/HEAPHASH, BTREE
  • algorithm_option:

    ALGORITHM [=] {DEFAULT | INPLACE | COPY}
  • lock_option:

    LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}

具体可参考MySQL 5.7 Reference Manual CREATE INDEX Syntax

三、优化

1. 如何才能命中索引

单列索引的话只要不作死基本就不会出现什么问题,本片文章主要讲讲联合索引的优化,相关的文档可以参考 MySQL 5.7 Reference Manual : multiple-column-indexes
MySQL可以创建复合索引(即多列上的索引)。索引最多可包含16列。对于某些数据类型,您可以索引列的前缀(请参见第8.3.4节“列索引”)。
在查询条件中用到索引的前一个字段、前两个字段、前三个字段、前N个字段时才会使用索引。如果在索引定义中以正确的顺序指定列,则单个复合索引可以加速同一表上的多种查询。
多列索引可以视为通过连接两个索引字段值来创建的有序数组。(原文A multiple-column index can be considered a sorted array, the rows of which contain values that are created by concatenating the values of the indexed columns.)

假设表的结构为:

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_name和first_name列的联合索引。这个索引用于last_name 和first_name values的组合范围查询。它还可以用于仅指定last_name值的查询,因为该列是索引的最左前缀。所以下面的这些查询将会使用到这个索引:

SELECT * FROM test WHERE last_name='Widenius';
SELECT * FROM test  WHERE last_name='Widenius' AND first_name='Michael';
SELECT * FROM test  WHERE last_name='Widenius'  AND (first_name='Michael' OR first_name='Monty');
SELECT * FROM test  WHERE last_name='Widenius'  AND first_name >='M' AND first_name < 'N';

但是下面的这些查询将不会使用这个联合索引:

SELECT * FROM test WHERE first_name='Michael';
SELECT * FROM test  WHERE last_name='Widenius' OR first_name='Michael';

2. 使用额外的列来代替索引

可以将多个列的hash值存放到一个列中来代替复合索引。如果这个列的值可以非常短、不会重复,可能比设置大量列的索引来的更高效。举个栗子:

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

四、参考资料

MySQL官方文档:SQL语句语法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值