1.添加PRIMARY KEY(主键索引)
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` );2.添加UNIQUE(唯一索引) mysql>ALTER TABLE `table_name` ADD UNIQUE (`column` ); 3.添加INDEX(普通索引) ALTER TABLE `table_name` ADD INDEX index_name (`column`) ;4.添加FULLTEXT(全文索引) ALTER TABLE `table_name` ADD FULLTEXT ( `column`) ;5.添加多列索引 ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` );使用CREATE INDEX语句对表增加索引。
能够增加普通索引和UNIQUE索引两种。其格式如下:create index index_name on table_name (column_list);create unique index index_name on table_name (column_list);删除索引
删除索引可以使用ALTER TABLE或DROP INDEX语句来实现。DROP INDEX可以在ALTER TABLE内部作为一条语句处理,其格式如下:drop index index_name on table_name;alter table table_name drop index index_name;alter table table_name drop primary key;其中,在前面的两条语句中,都删除了table_name中的索引index_name。而在最后一条语句中,只在删除PRIMARY KEY索引中使用,因为一个表只可能有一个PRIMARY KEY索引,因此不需要指定索引名。
如果没有创建PRIMARY KEY索引,但表具有一个或多个UNIQUE索引,则MySQL将删除第一个UNIQUE索引。
如果从表中删除某列,则索引会受影响。对于多列组合的索引,如果删除其中的某列,则该列也会从索引中删除。如果删除组成索引的所有列,则整个索引将被删除。删除索引的操作,如下面的代码:drop index index_name on table_test;查看索引
mysql> show index from tblname;
mysql> show keys from tblname;· Table表的名称。· Non_unique如果索引不能包括重复词,则为0。如果可以,则为1。· Key_name索引的名称。· Seq_in_index索引中的列序列号,从1开始。· Column_name列名称。· Collation列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。· Cardinality索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机 会就越大。· Sub_part如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。· Packed指示关键字如何被压缩。如果没有被压缩,则为NULL。· Null如果列含有NULL,则含有YES。如果没有,则该列含有NO。· Index_type用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。· CommentEXPLAIN: 建立索引前后,可以通过在查询语句前加上 EXPLAIN 来分析查询语句到底使用了哪些索引。
Explain后的结果中 type 列,这列很重要,显示了连接使用了哪种类别,有无使用索引。从最好到最差的连接类型为const、eq_ref、ref、range、indexhe和ALL。
System:这是const联接类型的一个特例。表仅有一行满足条件.如下 ID是 primary key
EXPLAIN SELECT * FROM(SELECT * FROM td_OfficialStoryAlbumAndAlbumTypes WHERE ID=17) a;
结果:
1 ,PRIMARY ,<derived2> ,system ,1
2 ,DERIVED ,td_OfficialStoryAlbumAndAlbumTypes ,const ,PRIMARY ,PRIMARY ,4 ,const, 1
const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。
eq_ref可以用于使用= 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。
ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。ref可以用于使用=或<=或>=操作符的带索引的列。
ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。
index_merge:该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。
unique_subquery:该类型替换了下面形式的IN子查询的ref:value IN (SELECT primary_key FROM single_table WHERE some_expr);unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:value IN (SELECT key_column FROM single_table WHERE some_expr);
range:索引范围扫描;
index:全索引扫描;
all:全表扫描;
索引优化
1、选择索引的数据类型MySQL支持很多数据类型,选择合适的数据类型存储数据对性能有很大的影响。通常来说,可以遵循以下一些指导原则:(1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。(2)简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。(3)尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。2、选择标识符
选择合适的标识符是非常重要的。选择时不仅应该考虑存储类型,而且应该考虑MySQL是怎样进行运算和比较的。一旦选定数据类型,应该保证所有相关的表都使用相同的数据类型。(1)整型:通常是作为标识符的最好选择,因为可以更快的处理,而且可以设置为AUTO_INCREMENT。(2)字符串:尽量避免使用字符串作为标识符,它们消耗更好的空间,处理起来也较慢。而且,通常来说,字符串都是随机的,所以它们在索引中的位置也是随机的,这会导致页面分裂、随机访问磁盘,聚簇索引分裂(对于使用聚簇索引的存储引擎)。3、索引存储的值按索引列中的顺序排列。可以利用B-Tree索引进行全关键字、关键字范围和关键字前缀查询,当然,如果想使用索引,你必须保证按索引的最左边前缀(leftmost prefix of the index)来进行查询。
(1)匹配全值(Match the full value):对索引中的所有列都指定具体的值。例如,上图中索引可以帮助你查找出生于1960-01-01的Cuba Allen。(2)匹配最左前缀(Match a leftmost prefix):你可以利用索引查找last name为Allen的人,仅仅使用索引中的第1列。(3)匹配列前缀(Match a column prefix):例如,你可以利用索引查找last name以J开始的人,这仅仅使用索引中的第1列。(4)匹配值的范围查询(Match a range of values):可以利用索引查找last name在Allen和Barrymore之间的人,仅仅使用索引中第1列。(5)匹配部分精确而其它部分进行范围匹配(Match one part exactly and match a range on another part):可以利用索引查找last name为Allen,而first name以字母K开始的人。(6)仅对索引进行查询(Index-only queries):如果查询的列都位于索引中,则不需要读取元组的值。由于B-树中的节点都是顺序存储的,所以可以利用索引进行查找(找某些值),也可以对查询结果进行ORDER BY。当然,使用B-tree索引有以下一些限制:(1) 查询必须从索引的最左边的列开始。关于这点已经提了很多遍了。例如你不能利用索引查找在某一天出生的人。(2) 不能跳过某一索引列。例如,你不能利用索引查找last name为Smith且出生于某一天的人。(3) 存储引擎不能使用索引中范围条件右边的列。例如,如果你的查询语句为WHERE last_name="Smith" AND first_name LIKE 'J%' AND dob='1976-12-23',则该查询只会使用索引中的前两列,因为LIKE是范围查询。4、Hash索引
MySQL中,只有Memory存储引擎显示支持hash索引,是Memory表的默认索引类型,尽管Memory表也可以使用B-Tree索引。Memory存储引擎支持非唯一hash索引,这在数据库领域是罕见的,如果多个值有相同的hash code,索引把它们的行指针用链表保存到同一个hash表项中。
假设创建如下一个表:
CREATE TABLE testhash ( fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, KEY USING HASH(fname)) ENGINE=MEMORY;包含的数据如下:Slots是有序的,但是记录不是有序的。当你执行
mysql> SELECT lname FROM testhash WHERE fname='Peter';
MySQL会计算’Peter’的hash值,然后通过它来查询索引的行指针。因为f('Peter') = 8784,MySQL会在索引中查找8784,得到指向记录3的指针。因为索引自己仅仅存储很短的值,所以,索引非常紧凑。Hash值不取决于列的数据类型,一个TINYINT列的索引与一个长字符串列的索引一样大。 Hash索引有以下一些限制:(1)由于索引仅包含hash code和记录指针,所以,MySQL不能通过使用索引避免读取记录。但是访问内存中的记录是非常迅速的,不会对性造成太大的影响。(2)不能使用hash索引排序。(3)Hash索引不支持键的部分匹配,因为是通过整个索引值来计算hash值的。(4)Hash索引只支持等值比较,例如使用=,IN( )和<=>。对于WHERE price>100并不能加速查询。2.1.3、空间(R-Tree)索引MyISAM支持空间索引,主要用于地理空间数据类型,例如GEOMETRY。2.1.4、全文(Full-text)索引全文索引是MyISAM的一个特殊索引类型,主要用于全文检索。太长了,实在不想抄了,自己看去:http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html
来源:http://www.cnblogs.com/lixiuran/p/6144319.html
http://www.cnblogs.com/cy163/archive/2008/10/27/1320798.html
http://www.cnblogs.com/discuss/articles/1862244.html
http://www.cnblogs.com/daxian2012/articles/2767989.html
http://blog.csdn.net/zm2714/article/details/7887093
方法:http://blog.163.com/lgh_2002/blog/static/4401752620105190332893/
EXPLAIN结果解释:http://blog.csdn.net/spring_yyy/article/details/12971183
解决inner join连接查询的索引使用:http://blog.csdn.net/spring_yyy/article/details/15450809