|
索引用来加速查询。正常来说,当查询数据时,MySQL 需要从表的第一条记录开始,读取整个表的内容,进行查询。
但如果有索引,MySQL 可根据索引快速定位需要查询条目的具体位置,加快了查询速度。
原理
索引的原理是将被索引列的值,单独取出来存到另一种结构中以获取快速查询的效果。
当列有这些属性中任意一个时,会被索引, PRIMARY KEY, UNIQUE, INDEX, 以及 FULLTEXT。
大部分索引以 B-trees 结构存储。但有些例外:
MySQL 使用索引的场景
以下场景将借助或依赖于索引:
- 使用
WHERE 进行条件查询时
- 用于排除一些记录。存在多个索引可选时,MySQL 选择会获取最小记录的那个索引(the most selective index)。
- 存在多列索引的情况下,从左排开始的列的组合都可用于查询时的优化。比如三个索引列 (col1, col2, col3),查询时可以有这些组合的优化查询 (col1), (col1, col2), and (col1, col2, col3),详见 Section 8.3.6, “Multiple-Column Indexes”。
- 联表查询时。特别地,如果列的类型及大小相同的话,查询时会更加高效。比如 VARCHAR 和 CHAR 会当成同一类型,VARCHAR(10) and CHAR(15) 则不是同一类型,因为长度不同。
- 使用 MIN(),MAX() 函数时。
- 进行排序或分组时。
- 某些情况下,仅仅通过索引就能完成查询操作,无须操作真实的表记录。这种提供了查询中足够信息的索引被称为 covering index。
索引并不是万能的,对于数据量小的表以及对于那些查询全部数据的操作,索引的效果并不明显。相反,对于那些查询时涉及到表中大部分数据的情况下,逐条查询比使用索引要快。
索引的类型
主要有以下四种索引类型,关于创建索引的其他详情可参见 MySQL Manual - 13.1.15 CREATE INDEX Syntax。
- 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)的搜索。只 InnoDB 和 MyISAM 两种引擎下的 CHAR,VARCHAR,TEXT 数据类型支持全文本索引。不像 Index Prefixes,该类型的索引是会对整列的。
Spatial 索引
Spatial Data 数据类型 上创建的索引。
MEMORY Storage Engine 中的索引
MEMORY 存储引擎默认使用 HASH 索引,但也支持 BTREE 索引。
索引的创建
索引可在创建表时创建,参考 13.1.20 CREATE TABLE Syntax,也可针对已有的表进行创建,使用 CREATE INDEX 语句。
创建索引的语法
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);
函数形式的索引在定义时需要满足以下的条件,否则抛错:
- 表达式使用括号包裹,以和列名或列的其他前缀属性区别开来。
/*
- MySQL(五) MySQL中的索引详讲
序言 之前写到MySQL对表的增删改查(查询最为重要)后,就感觉MySQL就差不多学完了,没有想继续学下去的心态了,原因可能是由于别人的影响,觉得对于MySQL来说,知道了一些复杂的查询,就够了,但是 ...
- 一、MySQL中的索引 二、MySQL中的函数 三、MySQL数据库的备份和恢复 四、数据库设计和优化(重点)
一.MySQL中的索引###<1>索引的概念 索引就是一种数据结构(高效获取数据),在mysql中以文件的方式存在.存储建立了索引列的地址或者指向. 文件 :(以某种数据 结构存放) 存放 ...
- MySQL中的索引详讲
一.什么是索引?为什么要建立索引? 索引用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的 ...
- mysql 中添加索引的三种方法
原文:http://www.andyqian.com/2016/04/06/database/mysqleindex/ 在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以 ...
- (转)MySQL中的索引详讲
序言 之前写到MySQL对表的增删改查(查询最为重要)后,就感觉MySQL就差不多学完了,没有想继续学下去的心态了,原因可能是由于别人的影响,觉得对于MySQL来说,知道了一些复杂的查询,就够了,但是 ...
- MySQL中是索引
MySQL中是索引: --.唯一索引: 一行中的内容不能一样, create t2( id int , num int, unique weiyisuiyin (id,num) ) --唯一; --约 ...
- 一步一步带你入门MySQL中的索引和锁 (转)
出处: 一步一步带你入门MySQL中的索引和锁 索引 索引常见的几种类型 索引常见的类型有哈希索引,有序数组索引,二叉树索引,跳表等等.本文主要探讨 MySQL 的默认存储引擎 InnoDB 的索引结 ...
- MySQL中的索引优化
MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 过多的使用索引将会造成滥用.因此索引也会有它的缺点.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行 ...
- MySQL中的索引简介
MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 一. 索引的优点 为什么要创建索引?这是因为,创建索引可以大大提高系统的查询性能. 第一.通过创建唯一性索引,可以保 ...
- java面试一日一题:讲下mysql中的索引
问题:请讲下mysql中的索引 分析:mysql中有很多索引,要对对这些索引有所掌握,还要弄清楚每种索引的本质? 回答要点: 主要从以下几点去考虑 1.索引的本质是什么 2.mysql的索引分类: 3 ...
随机推荐
- Java之多线程创建方式
多线程的由来 我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏边听歌,怎么设计?要解决上述问题,咱们得使用多进程或者多线程来解决. 多线程的好处: ...
- maven修改运行环境配置
maven中自带的tomcat是6版本,比如我们想用tomcat7,jdk1.8,我们就要通过配置来改变. 改变方式如下 <build> <plugins> <plugi ...
- ZooKeeper(四):从TCP数据流到zk内部处理包的转换
通过前面几篇文章,我们可以从整体上看到zk是如何处理网络数据的宏观架构. 本文我们从细节着手,看一下一个tcp的包是如何转换到内部的数据流处理的. 一.监听用户请求socket 基于NIO的端口监听, ...
- Docker容器日志路径
/var/lib/docker/containers/容器ID/容器ID-json.log 可以通过这个路径收集日志到ES中
- Python中常见的8种数据结构的实现方法(建议收藏)
数据结构作为计算机基础的必修内容,也是很多大型互联网企业面试的必考题.可想而知,它在计算机领域的重要性. 然而很多计算机专业的同学,都仅仅是了解数据结构的相关理论,却无法用代码实现各种数据结构. 栈 ...
- 使用PrintWriter完成写操作 ,实现简易记事本工具
package seday07; import java.io.BufferedWriter;import java.io.FileOutputStream;import java.io.IOExce ...
- 用两种以上的 方式实现一个方法或者对象,调用时打印"你好xx",已定义的代码不能做修改,自己编译的不能出现"你好"? (Javasctript)
先上代码 const obj = { say(){ Array.from(arguments).forEach(item=>{ console.log(`${this.str} ${item}` ...
- LOG日志溯源取证总结
windows操作系统事件日志 C:\Windows\System32\winevt\Logs\ *( XP C:\Windows\System32) 应用程序日志 App Event.Evtx(Ap ...
- 【React Native】进阶指南之二(手势响应系统)
移动设备上的手势识别要比在 web 上复杂得多.用户的一次触摸操作的真实意图是什么,App 要经过好几个阶段才能判断.比如 App 需要判断用户的触摸到底是在滚动页面,还是滑动一个 widget,或者 ...
- ABP入门教程7 - 基础设施层更新数据库
点这里进入ABP入门教程目录 设置数据库 在基础设施层(即JD.CRS.EntityFrameworkCore)打开数据库环境设置 JD.CRS.EntityFrameworkCore/EntityF ...
|