mysql的索引类型及使用索引时的注意事项有:
站在用户的角度思考问题,与客户深入沟通,找到丁青网站设计与丁青网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站设计、网站制作、企业官网、英文网站、手机端网站、网站推广、国际域名空间、虚拟主机、企业邮箱。业务覆盖丁青地区。
一、普通索引。这是最基本的索引,它没有任何限制。它有以下几种创建方式:
1、创建索引
代码如下:
CREATE INDEX indexName ON mytable(username(length));
如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length,下同。
2、修改表结构
代码如下:
ALTER mytable ADD INDEX [indexName] ON (username(length)) -- 创建表的时候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) );
-- 删除索引的语法:
DROP INDEX [indexName] ON mytable;
二、唯一索引。它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
代码如下:
CREATE UNIQUE INDEX indexName ON mytable(username(length))
-- 修改表结构
ALTER mytable ADD UNIQUE [indexName] ON (username(length))
-- 创建表的时候直接指定
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE [indexName] (username(length)) );
三、主键索引。它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引:
代码如下:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) );
当然也可以用 ALTER 命令。记住:一个表只能有一个主键。
四、组合索引。为了形象地对比单列索引和组合索引,为表添加多个字段:
代码如下:
CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL, age INT NOT NULL );
为了进一步榨取MySQL的效率,就要考虑建立组合索引。就是将 name, city, age建到一个索引里:
代码如下:
ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age);[code]
建表时,usernname长度为 16,这里用 10。这是因为一般情况下名字的长度不会超过10,这样会加速索引查询速度,还会减少索引文件的大小,提高INSERT的更新速度。
如果分别在 usernname,city,age上建立单列索引,让该表有3个单列索引,查询时和上述的组合索引效率也会大不一样,远远低于我们的组合索引。虽然此时有了三个索引,但MySQL只能用到其中的那个它认为似乎是最有效率的单列索引。
建立这样的组合索引,其实是相当于分别建立了下面三组组合索引:usernname,city,age usernname,city usernname 为什么没有 city,age这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这三列的查询都会用到该组合索引,下面的几个SQL就会用到这个组合索引:
[code]
SELECT * FROM mytable WHREE username="admin" AND city="郑州" SELECT * FROM mytable WHREE username="admin"
利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知 道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。
所以说创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用;仅对后面的任意列执行搜索时,复合索引则没有用处。
如:建立 姓名、年龄、性别的复合索引。
create table test(
a int,
b int,
c int,
KEY a(a,b,c)
);
优: select * from test where a=10 a
我个人建议用explain extended先得到一条简短的语句,然后用explain看看你的访问类型,根据explain进行索引添加,然后在执行语句。用show status like 'Handler_read%';查看你的索引使用情况,Handler_read_rnd_next很高意味着查询效率低下,说明你要换一个索引值。然后用show profile看看你的线程到底在哪里消耗的开销比较大。
引入一个面试问题:
看完以下以后再回顾,会发现迎刃而解
Mysql 可以为每一张表设置 存储引擎 这里我们只说 InnoDB 存储引擎.
由于实际情况,数据页只能按照一棵 B+树 进行排序, 因此每张表只能拥有一个 聚集索引(即 主键)。
栗子:
每个叶子节点的索引行中包含了一个书签(bookmark). 该书签是用来告诉 InnoDB存储引擎哪里可以找到该索引对应的数据行或者说 行数据! 由于InnoDB存储引擎表, 是按照主键来构建的, 所以 ,该书签内其实包含或者说指向了 数据行所对应的聚集索引键
也就是说 辅助索引的 叶结点保存了 指向对应数据的 聚集索引, 可以通过该聚集索引 找到对应的数据行
辅助索引的存在并不影响数据在聚集索引中的组织,因为每张表上可以有多个辅助索引。
当通过辅助索引来寻找数据时,InnoDB 存储引擎会遍历辅助索引并通过叶级别的指针获得指向主键索引(聚集索引)的主键,然后再通过聚集索引找到一个完整的数据行。
例如:
聚集索引辅助索引关系:
: 又叫做组合索引 , 辅助索引的一种 , 和普通创建索引的方式一样,不同的是 可以同时添加多列来作为索引项;
从本质上来说,联合索引也是一课B+树
个人理解: 所谓最左原则, 是因为 存储引擎构建组合索引时 是根据最左边的那一列索引项进行排序的 ,所以使用组合索引,必须满足 条件中必须存在 最左边那一列的索引项,这样 才可以找到对应的索引,继而 去寻找对应的数据
: 又叫做 索引覆盖,InnoDB中支持覆盖索引,即 从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。
比如 这里没有根据最左原则使用组合索引,但是 优化器依然进行选择
共勉,欢迎指导谢谢~
1.选择唯一性索引
唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话,可能存在同名现象,从而降低查询速度。
2.为经常需要排序、分组和联合操作的字段建立索引
经常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作会浪费很多时间。如果为其建立索引,可以有效地避免排序操作。
3.为常作为查询条件的字段建立索引
如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度。因此,为这样的字段建立索引,可以提高整个表的查询速度。
4.限制索引的数目
索引的数目不是越多越好。每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。
5.尽量使用数据量少的索引
如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。
6.尽量使用前缀来索引
如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。
7.删除不再使用或者很少使用的索引
表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。
8 . 最左前缀匹配原则,非常重要的原则。
mysql会一直向右匹配直到遇到范围查询(、、between、like)就停止匹配,比如a 1=”” and=”” b=”2” c=”“ 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
9 .=和in可以乱序。
比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
。
10 . 尽量选择区分度高的列作为索引。
区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就 是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条 记录
11 .索引列不能参与计算,保持列“干净”。
比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本 太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);
12 .尽量的扩展索引,不要新建索引。
比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
注意:选择索引的最终目的是为了使查询的速度变快。上面给出的原则是最基本的准则,但不能拘泥于上面的准则。读者要在以后的学习和工作中进行不断的实践。根据应用的实际情况进行分析和判断,选择最合适的索引方式。