博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL 中的索引
阅读量:4618 次
发布时间:2019-06-09

本文共 3149 字,大约阅读时间需要 10 分钟。

索引用来加速查询。正常来说,当查询数据时,MySQL 需要从表的第一条记录开始,读取整个表的内容,进行查询。

但如果有索引,MySQL 可根据索引快速定位需要查询条目的具体位置,加快了查询速度。

原理

索引的原理是将被索引列的值,单独取出来存到另一种结构中以获取快速查询的效果。

当列有这些属性中任意一个时,会被索引, PRIMARY KEYUNIQUEINDEX, 以及 FULLTEXT

大部分索引以 结构存储。但有些例外:

  • ,一种基于地理坐标使用数字来标识现实中对象的数据类型,使用 。
  • MEMORY 内存表同时支持使用 。
  • InnoDB 引擎中对于全文本索引(FULLTEXT)直接使用列表(lists)结构。

MySQL 使用索引的场景

以下场景将借助或依赖于索引:

  • 使用 WHERE 进行条件查询时
  • 用于排除一些记录。存在多个索引可选时,MySQL 选择会获取最小记录的那个索引(the most  index)。
  • 存在多列索引的情况下,从左排开始的列的组合都可用于查询时的优化。比如三个索引列 (col1, col2, col3),查询时可以有这些组合的优化查询 (col1), (col1, col2), and (col1, col2, col3),详见 。
  • 联表查询时。特别地,如果列的类型及大小相同的话,查询时会更加高效。比如 VARCHAR 和 CHAR 会当成同一类型,VARCHAR(10) and CHAR(15) 则不是同一类型,因为长度不同。
  • 使用 , 函数时。
  • 进行排序或分组时。
  • 某些情况下,仅仅通过索引就能完成查询操作,无须操作真实的表记录。这种提供了查询中足够信息的索引被称为 。

索引并不是万能的,对于数据量小的表以及对于那些查询全部数据的操作,索引的效果并不明显。相反,对于那些查询时涉及到表中大部分数据的情况下,逐条查询比使用索引要快。

索引的类型

主要有以下四种索引类型,关于创建索引的其他详情可参见 。

  • Index Prefixes
  • FULLTEXT 索引
  • Spatial 索引
  • MEMORY Storage Engine 中的索引

Index Prefixes

对于字符串类型的列,在索引创建语法中指定 col_name(N),可将该列中前 N 个字符进行索引。通过只索引列中前 N 个字符 而非整列,可有效减小索引大小。比如索引 BLOB or TEXT 类型的列:

CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));

查询时,如果查询项超过了索引长度,索引将用来排除掉那些在索引长度范围内匹配失败的记录,剩下的记录则正常查询。

FULLTEXT 索引

全文本索引用于全文本(full-text)的搜索。只 和 两种引擎下的 CHAR,VARCHAR,TEXT 数据类型支持全文本索引。不像 Index Prefixes,该类型的索引是会对整列的。

Spatial 索引

上创建的索引。

MEMORY Storage Engine 中的索引

 MEMORY 存储引擎默认使用 HASH 索引,但也支持 BTREE 索引。

索引的创建

索引可在创建表时创建,参考 ,也可针对已有的表进行创建,使用 语句。

创建索引的语法
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)] | (expr)} [ASC | DESC]index_option:    KEY_BLOCK_SIZE [=] value  | index_type  | WITH PARSER parser_name  | COMMENT 'string'  | {VISIBLE | INVISIBLE}index_type:    USING {BTREE | HASH}algorithm_option:    ALGORITHM [=] {DEFAULT | INPLACE | COPY}lock_option:    LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}

有如下类型的索引指定方式,

  • 以列前缀的方/Column Prefix Key Parts
  • 函数形式/Functional Key Parts
  • Unique 索引
  • Full-Text 索引
  • Spatial 索引

以列前缀的方

可用于创建列中指定前缀部分 col_name(length) 的索引。

示例:

CREATE INDEX part_of_name ON customer (name(10));

以上语句对名为 name 的例索引其前 10 个字符。

函数形式

普通形式的索引只能索引列中的值,比如:

CREATE TABLE t1 (  col1 VARCHAR(10),  col2 VARCHAR(20),  INDEX (col1, col2(10)));

以上语句对 col1 整列 及 col2 前 10 个字符进行索引。

但使用函数形式,可创建针对表达式的索引,而不是表中的列。

CREATE TABLE t1 (col1 INT, col2 INT, INDEX func_index ((ABS(col1))));CREATE INDEX idx1 ON t1 ((col1 + col2));CREATE INDEX idx2 ON t1 ((col1 + col2), (col1 - col2), col1);ALTER TABLE t1 ADD INDEX ((col1 * 40) DESC);

函数形式的索引在定义时需要满足以下的条件,否则抛错:

  • 表达式使用括号包裹,以和列名或列的其他前缀属性区别开来。
/* ? */INDEX (col1 + col2, col3 - col4)/* ✅ */INDEX ((col1 + col2), (col3 - col4))
  • 函数形式的表达式不能形成一个单独的列名,譬如:
/* ? */INDEX ((col1), (col2))/* ✅ */INDEX (col1, col2)
  • 函数中不能引用列前缀(column prefixes)。
  • 外键(foreign key)中不使用使用函数形式。

Unique 索引

指定为 UNIQUE 的列约束了列中的值在记录中是唯一的,尝试插入重复值时会抛错。但允许存在多个 NULL 值,如果该列允许为空的话。

如果一个表拥有 PRIMARY KEYUNIQUE NOT NULL 类型的单列整型形成的索引,在 SELECT 语句中可使用 _rowid 关键词来获取索引的列:

  • 如果存在一个整型的 PRIMARY KEY 列,_rowid 则指代该列。
  • 否则 _rowid 指代第一个 UNIQUE NOT NULL 列。如果不存在一个 UNIQUE NOT NULL 类型的整型列,则不能使用 _rowid

Full-Text 索引

详细的操作参见 。

Spatial 索引

不同存储引擎对其支持情况不一,详见 。

相关资源

转载于:https://www.cnblogs.com/Wayou/p/mysql_index.html

你可能感兴趣的文章
HDU 1890--Robotic Sort(Splay Tree)
查看>>
connection string for Excel/Access 2010
查看>>
【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)
查看>>
学习wavenet_vocoder之环境配置
查看>>
常用Maven命令
查看>>
Docker启动mysql的坑2
查看>>
j2ee爬坑行之二 servlet
查看>>
JAVA基础入门(JDK、eclipse下载安装)
查看>>
最基础的applet运用--在applet上画线
查看>>
并不对劲的hdu4777
查看>>
linux使用rz、sz快速上传、下载文件
查看>>
判断数字的正则表达式
查看>>
DOC常用命令(转)
查看>>
php写一个判断是否有cookie的脚本
查看>>
Mac配置Fiddler抓包工具
查看>>
转:Java并发集合
查看>>
Word截图PNG,并压缩图片大小
查看>>
Python项目对接CAS方案
查看>>
mysql产生随机数
查看>>
编程风格
查看>>