暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

怎样查看索引是否有高选择性?

摘星族 2017-05-11
465

创建索引

 

(1) 主键索引

它是一种特殊的唯一索引,不允许有空值。一般是在创建表的同时创建主键索引:

CREATE TABLE user(

id int unsigned not null auto_increment,

name varchar(50) not null,

email varchar(40) not null,

primary key (id)

);

 

(2)普通索引

这是最基本的索引,它没有任何限制:

 

CREATE INDEX index_name user(name(20));

mysql支持前缀索引,一般姓名不会超过20个字符,所以我们这里建立索引的时候限定了长度20,这样可以节省索引文件大小。

 

(3)唯一索引

它与前面的普通索引类似,不同的就是:索引列的值必须唯一。但允许有空值,如果是组合索引,则列值的组合必须唯一:

 

CREATE UNIQUE INDEX index_email ON user(

email

);

 

(4)全文索引

MySQL支持全文索引和搜索功能。MySQL中的全文索引类型为FULLTEXT的索引。  FULLTEXT 索引仅可用于 MyISAM

 

CREATE TABLE articles (

   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,

   title VARCHAR(200),

   body TEXT,

   FULLTEXT (title,body)

);

 

(5)复合索引

 

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,或者为last_name first_name在已知范围内指定值的查询。因此,name索引用于下面的查询:

SELECT * FROM test WHERE last_name='zhangsan';

SELECT * FROM test WHERE last_name='zhangsan' AND first_name='lisi';

但是不能用于SELECT * FROM test WHERE first_name='lisi';这是因为MySQL组合索引为“最左前缀”的结果,简单的理解就是只从最左面的开始组合。

 

在什么情况下使用索引


        为搜索字段建立索引,如果在你的表中,某个字段你经常 用来做搜索,那么,请为其建立索引吧。一般来说,在WHEREJOIN中出现的列需要建立索引以提高查询速度。


        创建索引可以大大提高系统的性能。第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

 

        索引有大量的数据的时候建立,没有大量的数据反而会浪费时间,因为索引是使用二叉树建立,索引并不是越多越好,太多的索引会占用很多的索引表空间,甚至比存储一条记录更多。对于需要频繁新增记录的表,最好不要创建索引,没有索引的表执行insertappend都很快,有了索引以后,会多一个维护索引的操作,一些大表可能导致insert 速度非常慢。


下面我们就来看看这个EXPLAIN分析结果的含义


 

table:这是表的名字。 
type:连接操作的类型。下面是MySQL文档关于ref连接类型的说明:
 
        “对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUEPRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。在本例中,由于索引不是UNIQUE类型,ref是我们能够得到的最好连接类型。 如果EXPLAIN显示连接类型是“ALL”,而且你并不想从表里面选择出大多数记录,那么MySQL的操作效率将非常低,因为它要扫描整个表。你可以加入更多的索引来解决这个问题。预知更多信息,请参见MySQL的手册说明。

 
possible_keys 
可能可以利用的索引的名字。这里的索引名字是创建索引时指定的索引昵称;如果索引没有昵称,则默认显示的是索引中第一个列的名字
(在本例中,它是“idx_name”)。


Key 
它显示了MySQL实际使用的索引的名字。如果它为空(或NULL),则MySQL不使用索引。 


key_len 
索引中被使用部分的长度,以字节计。


ref 
它显示的是列的名字(或单词“const”),MySQL将根据这些列来选择行。在本例中,MySQL根据三个常量选择行。 


rows 
MySQL所认为的它在找到正确的结果之前必须扫描的记录数。显然,这里最理想的数字就是1


Extra 
这里可能出现许多不同的选项,其中大多数将对查询产生负面影响。在本例中,MySQL只是提醒我们它将用using whereusing index子句限制搜索结果集。

 

 MySQL查看索引


        若要查看该表创建的索引,使用SHOW INDEXES语句,若要删除索引,请使用DROP INDEX语句。



· Table

表的名称。

· Non_unique

如果索引不能包括重复词,则为0。如果可以,则为1

· Key_name

索引的名称。

· Seq_in_index

索引中的列序列号,从1开始。

· Column_name

列名称。

· Collation

列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。

· Cardinality

索引中唯一值的数目的估计值。通过运行ANALYZE TABLEmyisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机 会就越大。

· Sub_part

如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL

· Packed

指示关键字如何被压缩。如果没有被压缩,则为NULL

· Null

如果列含有NULL,则含有YES。如果没有,则该列含有NO

· Index_type

用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

· Comment

 


         不管数据表有无索引,首先在SGA的数据缓冲区中查找所需要的数据,如果数据缓冲区中没有需要的数据时,服务器进程才去读磁盘。

1、无索引,直接去读表数据存放的磁盘块,读到数据缓冲区中再查找需要的数据。

2、有索引,先读入索引表,通过索引表直接找到所需数据的物理地址,并把数据读入数据缓冲区中。


END!!!


Good Luck!!!




文章转载自摘星族,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论