mysql 索引问题
转自http://www.blogjava.net/happyenjoylife/archive/2011/12/17/366639.html
mysql innodb存储与索引的总结
Innodb存储
表空间是逻辑存放所有数据的地方,默认情况下会共享一个表空间——ibdata1,但如果把innodb_file_per_table=ON后每张表可以单独放到一个表空间内,但还是有很多数据保存在共享的表ibdata1中,如undo信息等。
表空间由各种段(segment)组成,常见的段有数据段、索引段等。Innodb是索引组织的,数据段就是clustered index的叶结点。需要注意的是,不是每个对象都有段。
区(extend)是由64个连续的页组成,每个页(page)固定为16KB,所以每个区总共为1M。页是innodb最小的磁盘管理单位。
Innodb是按行进行存放的,每个区最少可以保存2条记录,否则就成链式结构了。每行数据除了自定义列以外,还会增加事务id和回滚指针列。如果没有定义primary key也没有not null的unique,则会增加6字节的RowId列作为主键。

图片来自:http://www.cnblogs.com/chjw8016/archive/2011/03/08/1976891.html
Innodb表的限制
一个表不能包含超过1000列。
内部最大键长度是3500字节,但MySQL自己限制这个到1024字节。
除了VARCHAR, BLOB和TEXT列,最大行长度稍微小于数据库页的一半。即,最大行长度大约8000字节。LONGBLOB和LONGTEXT列必须小于4GB, 总的行长度,页包括BLOB和TEXT列,必须小于4GB。InnoDB在行中存储VARCHAR,BLOB或TEXT列的前768字节,余下的存储的分散的页中。
虽然InnoDB内部地支持行尺寸大于65535,你不能定义一个包含VARCHAR列的,合并尺寸大于65535的行。
· mysql> CREATE TABLE t (a VARCHAR(8000), b VARCHAR(10000),
· -> c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
· -> f VARCHAR(10000), g VARCHAR(10000));
· ERROR 1118 (42000): Row size too large. The maximum row size for the
· used table type, not counting BLOBs, is 65535. You have to change some
· columns to TEXT or BLOBs
在一些更老的操作系统上,数据文件必须小于2GB。
InnoDB日志文件的合并尺寸必须小于4GB。
最小的表空间尺寸是10MB。最大的表空间尺寸是4,000,000,000个数据库页(64TB)。这也是一个表的最大尺寸。
InnoDB表不支持FULLTEXT索引
Innodb索引
默认情况下Memory使用存储hash索引,但也支持b+tree索引。Hash索引只用于=或者<=>的等式比较,不能用来加速order by操作,只能通过关键字来搜索一行。innodb只支持b+树索引,进一步分为clustered index 与 secondary index。在一次查询中,只能使用一个索引。
Innodb是索引组织表,clustered index的叶结点保存着整行的数据。如果,定义了primary key,则clustered index就是primary key的索引;如果没有定义primary key mysql会选中第一个仅有not null列的unique索引作为主键,并把此索引当作clustered index使用;如果没找到这样的列,innodb会创建一个6字节的RowId作为主键。所以每张表有且只有一个clustered index。
Secondary index的叶结点不包括行的全部数据,包含键值以外还包括一个bookmark,可以告诉innodb到什么地方可以找到相对应的完整行数据,还保存了主键的健值。Secondary index包含主键,但不包含完整的行数据,所以innodb总是会先从secondary index的叶节点判断是否能得到所需的数据。如,
Create table t(a int, b varchar(20), primary key(a), key(b));
Explain select * from t;
会发现mysql选择了索引b,而不是a.
复合索引
复合索引是在多列(>=2)上建立的索引,又叫多列索引或联合索引。Innodb中的复合索引也是b+ tree结构。索引的数据包含多列(col1, col2, col3…),在索引中依次按照col1, col2, col3排序。如(1, 2), (1, 3),(2,0)…
使用复合索引要充分利用最左前缀原则,顾名思义,就是最左优先。如创建索引ind_col1_col2(col1, col2),那么在查询where col1 = xxx and col2 = xx或者where col1 = xxx都可以走ind_col1_col2索引。
在创建多列索引时,要根据业务需求,where子句中使用最频繁且过滤效果好的的一列放在最左边。
索引操作
可以通过DML语句操作innodb索引。因为innodb是索引组织的表,对索引的操作会造成锁表,先生成一张临时表,将数据从原始表中写到临时表,再将原始表删除,最后将临时表表名改为原始表表名!因增加、删除、修改字段会对主索引产生影响,所以也会锁表。对secondary index从Innodb plugin开始,支持快速索引创建的方法,在创建的过程中不需要重建表,所以速度会很快,同时引擎会在表上加S锁,在创建过程中只能进行读操作。
索引设计原则
1. 搜索的索引列,不一定是所要选择的列。也就是说,最适合索引的列是出现在where子句中的列,或者连接子句中指定的列,而不是出现在select关键字后的选择列表中的列。
2. 使用唯一索引。考虑某列的分布,索引的列的基数越大,索引的效果越好。例如,对性别M/F列做索引没多大用处。
3. 使用短索引。如果是对字符串进行索引,如果有可能应该指定前缀长度。
4. 利用最左前缀。尽量将使用频繁且过滤效果好的字段放“左边”
5. 不要过度索引。
6. Innodb默认会按照一定的顺序保存数据,如果明确定义了主键,则按照主键顺序保存。如果没有主键,但有唯一索引,就按照唯一索引的顺序保存。如果有几个列都是唯一的,都可以作为主键的时候,为了提高查询效率,应选择最常用访问的列作为主键。另外,innodb的secondary index都会保存主键的键值,所有主键要尽可能选择较短的数据类型。可以看出,应当尽量避免对主键的修改。经过dba的测试,保证主键的递增可以提高插入性能。
Mysql如何使用索引
1. 对于创建的多列索引,只要查询的条件中用到了最左边的列,索引一般就会被使用。
2. 对于使用like的查询,后面如果是常量并且只有%号不在第一个字符,索引才可能被使用。
3. 如果对大文本进行搜索,应该使用全文索引,而不是使用like ‘%...%’. 但不幸的是innodb不支持全文索引。
4. 如果列名是索引,使用 index_column is null将使用索引。Oracle是不行的。
5. 如果mysql估计使用索引比全表扫描更慢,最不会使用索引。
6. 如果使用memory/head表并且where条件中不使用”=”进行索引列,那么不会用到索引。Head表只有在”=”的时候才会使用索引。
7. 用or分割开的条件,如果or前的条件中的列有索引,而后面列中没有索引,那么涉及到的索引都不会被用到。
8. 不是多列索引的第一部分不会走索引。
9. 以%开始的like不会走索引
10. 如果列是字符串,那么一定要在where条件中把字符串常量值用引号引起来,否则不能走索引。因为,mysql默认把输入的常量值进行转换以后才进行检索。
11. 经过普通运算或函数运算后的索引字段不能使用索引
12. 不等于操作不能使用索,<>、not in等
13. Order by 优化:某些情况下,mysql可以使用一个索引满足order by,而不需要额外的排序。Where条件与order by 使用相同的索引,并且order by的顺序和索引顺序相同,并且order by的字段都是升序或者都是降序。
SELECT * FROM t1 ORDER BY key_part1,key_part2,... ;
SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC, key_part2
DESC;
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;
但是以下情况不使用索引:
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC ;
--order by 的字段混合 ASC 和 DESC
SELECT * FROM t1 WHERE key2=constant ORDER BY key1 ;
-- 用于查询行的关键字与 ORDER BY 中所使用的不相同
SELECT * FROM t1 ORDER BY key1, key2 ;
-- 对不同的关键字使用 ORDER BY
可以使用explain查看sql的执行计划。
mysql 索引问题的更多相关文章
- 深入MySQL索引
MySQL索引作为数据库优化的常用手段之一在项目优化中经常会被用到, 但是如何建立高效索引,有效的使用索引以及索引优化的背后到底是什么原理?这次我们深入数据库索引,从索引的数据结构开始说起. 索引原理 ...
- MySQL 索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是 ...
- MYSQL索引结构原理、性能分析与优化
[转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...
- MySQL索引原理及慢查询优化
原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...
- 【转】MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- [转]MySQL索引背后的数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- MySQL索引类型总结和使用技巧以及注意事项
索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable ...
- MySQL索引背后的数据结构及算法原理【转】
本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...
- mysql索引总结----mysql 索引类型以及创建
文章归属:http://feiyan.info/16.html,我想自己去写了,但是发现此君总结的非常详细.直接搬过来了 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基 ...
- Mysql 索引实现原理. 聚集索引, 非聚集索引
Mysql索引实现: B-tree,B是balance,一般用于数据库的索引.使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度.而B+tree是B-tree的一个变种,My ...
随机推荐
- linux命令(3):pwd命令
Linux中用 pwd 命令来查看”当前工作目录“的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置. ...
- Win10切换中英输入法问题
用此方法解决后的效果: Win10系统只剩下"美式键盘"和"搜狗拼音"两种输入法,且默认为美式键盘. 按Ctrl+Shift切换到搜狗拼音,输入完成后,再按Ct ...
- hdu 3307 Description has only two Sentences (欧拉函数+快速幂)
Description has only two SentencesTime Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- Android多线程编程之AsyncTask
进程?线程? 进程是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态的概念.每个进程都有自己的地址空间(进程空间).进程空间的大小与处理机位数有关.进程至少有5种基本状态:初始态,执行态 ...
- C#中的?和??的用法
1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; 是正确的,int i=null; 编译器就会报错.为了使值类型也 ...
- [z]oracle job
我们在项目开发中,常常会有一些复杂的业务逻辑.使用oracle的存储过程,可以大大减少Java程序代码的编写工作量,而且存储过程执行在数据库上,这样可以利用oracle的良好性能支持,极大地提高程序执 ...
- Object.create()方法的低版本兼容问题
Object.prototype.create=(function(){ if(Object.prototype.create){return Object.prototype.create}else ...
- Source Insight 3.X utf8支持插件更新
[更新内容] 修复了当UTF8文件外部改变时,SI无法检测到的bug. 实现 [下载地址] 点我 [计划] 未来(无限长)优化utf8编码检测规则,提高准确度.
- js+html+jquery 个人笔记
js+html+jquery 笔记 1.获取HTML对象 var obj = document.getElementById(elementId) 对象的值: obj.value() 2.获取jQue ...
- Javascript.ReactNative-2-javascript-syntax-in-react-native
JavaScript Syntax in React Native Contents: Arrow Function Let+Const Default + Rest + Spread Destruc ...