删除索引可利用
ALTER TABLE
或
DROP INDEX
语句来删除索引。类似于
CREATE INDEX
语句,
DROP INDEX
可以在
ALTER TABLE
内部作为一条语句处理,语法如下。
(1)
DROP INDEX index_name ON talbe_name
(2)
ALTER TABLE table_name DROP INDEX index_name
(3)
ALTER TABLE table_name DROP PRIMARY KEY
第 3 条语句只在删除
PRIMARY KEY
索引时使用,因为一个表只可能有一个
PRIMARY KEY
索引,因此不需要指定索引名。
在 MySQL 5.5 之前,对于索引的添加或者删除,每次都需要创建一张临时表,然后导入数据到临时表,接着删除原表,如果一张大表进行这样的操作,会非常的耗时,这是一个很大的缺陷。
InnoDB 存储引擎从 1.0.x 版本开始加入了一种 Fast Index Creation
(快速索引创建)
的索引创建方式。
这种方式的策略为:每次为创建索引的表加上一个 S 锁
(共享锁)
,在创建的时候,不需要重新建表,删除辅助索引只需要更新内部视图,并将辅助索引空间标记为可用,所以,这种效率就大大提高了。
create
table t_index( a char(2) notnulldefault'', b char(2) notnulldefault'', c char(2) notnulldefault'', d char(2) notnulldefault'' )engine myisam charset utf8;
EXPLAINSELECT * FROM t_index WHERE a = 'a2'AND b = 'b2'ORDERBY d \G;
这种情况又有点不一样了,我们使用了一个排序,可以看出使用了索引,通过
key_len
为 12 可以得到使用了 2 个索引
a、b
,另外在 Extra 选项中可以看到使用了
Using filesort
,也就是文件排序,这里使用文件排序的原因是这样的:上面的查询使用了 a、b 索引,但是当我们用 d 字段来排序时,(a,d)或者(b,d)这两个索引是没有排序的,联合索引的使用有一个好处,就是索引的下一个字段是会自动排序的,在这里的这种情况来说,c 字段就是排序的,但是 d 是不会,如果我们用 c 来排序就会得到不一样的结果。
EXPLAINSELECT * FROM t_index WHERE a = 'a2'AND b = 'b2'ORDERBY c \G;
是不是可以看到,当我们用 c 进行排序的时候,因为使用了 a、b 索引,所以 c 就自动排序了,所以也就不用 filesort 了。
讲到这里,我相信通过上面的几个例子,对于联合索引的相关知识已经非常的透彻清晰了,最后,我们再来聊几个常见的问题。
覆盖索引。
对联合索引(col1,col2,col3),如果有如下的 sql: select col1,col2,col3 from test where col1=1 and col2=2。那么 MySQL 可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机 io 操作。减少 io 操作,特别的随机 io 其实是 dba 主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。
效率高。
索引列越多,通过索引筛选出的数据越少。有 1000W 条数据的表,有如下 sql:select from table where col1=1 and col2=2 and col3=3,假设假设每个条件可以筛选出 10% 的数据,如果只有单值索引,那么通过该索引能筛选出 1000W10%=100w 条数据,然后再回表从 100w 条数据中找到符合 col2=2 and col3= 3 的数据,然后再排序,再分页;如果是联合索引,通过索引筛选出 1000w10% 10% *10%=1w,效率提升可想而知!