Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL添加索引及字段并建立索引

MySQL添加索引及添加字段并建立索引方式

作者:人间寥寥情难诉

这篇文章主要介绍了MySQL添加索引及添加字段并建立索引方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

MySQL添加索引及字段并建立索引

添加字段并设置字段主键

alter table table_name drop primary key;
alter table table_name add column column2 varchar(10) NOT NULL COMMENT 'column2' AFTER column2;
alter table table_name add constraint user_test primary key(column_list); 

新建索引

使用CREATE语句创建索引:

CREATE INDEX index_name ON table_name(column_name1,column_name2);
CREATE UNIQUE INDEX index_name ON table_name(column_name);
CREATE PRIMARY KEY INDEX index_name ON table_name(column_name); 

使用ALTER TABLE语句创建索引:

alter table table_name add index index_name (column_list);
alter table table_name add unique index_name (column_list);
alter table table_name add primary key (column_list);
alter table table_name add fulltext index_name (column_list);

该语句指定了索引为 fulltext。

删除索引

drop index index_name on table_name;
alter table table_name drop index index_name;
alter table table_name drop primary key; 

修改

alter table table_name rename index old_index_name to new_index_name;
alter table table_name drop index old_index_name
alter table table_name add index new_index_name(column_list)

查询

使用 show index 命令来列出表中的相关的索引信息。

可以通过添加 \g 来格式化输出信息。

show index from table_name \g

MySQL索引介绍及使用

MySQL索引介绍

1. 概念

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。可以得到索引的本质:索引是排好序的快速查找数据结构。一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。

2.优势

3.劣势

4.使用原则

5. mysql索引结构

6. 哪些情况需要创建索引

7. 哪些情况不需要创建索引

8. 创建索引的语句

CREATE TABLE table_name[col_name data type]
[unique|fulltext][index|key][index_name](col_name[length])[asc|desc]

9. 删除索引的语句

DROP INDEX 索引名 ON 表名;
## 删除book表中的名称为BkNameIdx的索引
DROP INDEX BkNameIdx ON book;

10. 查看表的索引

## 查看表的索引
SHOW INDEX FROM book;

mysql索引分类及使用

MySQL中分为:普通索引,唯一索引,主键索引,组合索引,和全文索引。

1. 普通索引

是最基本的索引,它没有任何限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。。

它有以下几种创建方式:

# 1.直接创建索引
CREATE INDEX index_name ON table(column(length))
 
# 2.修改表结构的方式添加索引
ALTER TABLE table_name ADD INDEX index_name ON (column(length))
 
# 3.创建表的时候同时创建索引
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    INDEX index_name (title(length))
)
 
# 4.删除索引
DROP INDEX index_name ON table

2. 唯一索引

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

它有以下几种创建方式:

# 1.创建唯一索引
CREATE UNIQUE INDEX indexName ON table(column(length))
 
# 2.修改表结构
ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))
 
# 3.创建表的时候直接指定
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
     UNIQUE indexName (title(length))
);

3. 主键索引

是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。

一般是在建表的时候同时创建主键索引:

CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) NOT NULL ,
     PRIMARY KEY (`id`)
);

4. 组合索引

指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。

使用组合索引时遵循最左前缀集合

#添加组合索引
ALTER TABLE `table` ADD INDEX name_city_age (id,name,age); 
 
#创建组合索引
CREATE TABLE tab3(
id INT(4) NOT NULL,
name CHAR(20) NOT NULL,
age INT(3) NOT NULL,
info VARCHAR(255),
INDEX multiIdx(id,name,age)
);

最左前缀:组合索引遵从了最左前缀,利用索引中最左边的列集来匹配行,这样的列集称为最左前缀。例如,这里由id、name和age3个字段构成的索引,索引行中就按id/name/age的顺序存放,索引组合中的字段可以是(id,name,age)、(id,name)或者(id)。如果要查询的字段不构成最左面的前缀原则,那么就不会用索引,比如,age或者(name,age)组合就不会使用索引查询。

5. 全文索引

主要用来查找文本中的关键字,而不是直接与索引中的值相比较。

fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。

fulltext索引配合match against操作使用,而不是一般的where语句加like。

它可以在create table,alter table ,create index使用,不过目前只有char、varchar,text 列上可以创建全文索引。

值得一提的是,在数据量较大时候,现将数据放入一个没有全局索引的表中,然后再用CREATE index创建fulltext索引,要比先为一张表建立fulltext然后再将数据写入的速度快很多。

# 1.创建表的适合添加全文索引
CREATE TABLE `table` (
    `id` int(11) NOT NULL AUTO_INCREMENT ,
    `title` char(255) CHARACTER NOT NULL ,
    `content` text CHARACTER NULL ,
    `time` int(10) NULL DEFAULT NULL ,
    PRIMARY KEY (`id`),
    FULLTEXT (content)
);
 
# 2.修改表结构添加全文索引
ALTER TABLE article ADD FULLTEXT index_content(content)
 
# 3.直接创建索引
CREATE FULLTEXT INDEX index_content ON article(content)

Explain

1. 概念

Explain(查看执行计划),使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。

分析你的查询语句或是表结构的性能瓶颈。

2. 功能

3. 使用方法

Explain+SQL语句,例如

# 创建唯一索引
CREATE TABLE tab1(
id INT(5) NOT NULL,
name CHAR(20) NOT NULL,
UNIQUE INDEX uniqId(id)
);
 
# 查看索引使用信息
EXPLAIN SELECT * FROM tab1 WHERE id = 1;

4.执行计划包含的信息

id: select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序

select_type:查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询

table:显示这一行的数据是关于哪些表的。

type显示的是访问类型,是较为重要的一个指标

结果值从最好到最坏依次是:system>const>eq_ref>ref>range>index>All

一般来说,得保证查询至少达到range级别,最好能达到ref

possible_keys:显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出。但不一定被查询实际使用。

key:实际使用的索引。如果为NULL,则没有使用索引。查询中若使用了覆盖索引,则该索引仅出现在key列表中,不会出现在possible_keys列表中。(覆盖索引:查询的字段与建立的复合索引的个数一一吻合)

key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好。key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值。查询中与其它表关联的字段,外键关系建立索引。

rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。

Extra:包含不适合在其他列中显示但十分重要的额外信息。

单表索引优化案例分析

#创建表的SQL语句
CREATE TABLE article(
	id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
	author_id INT(10) UNSIGNED NOT NULL,
	category_id INT(10) UNSIGNED NOT NULL,
	views INT(10) UNSIGNED NOT NULL,
	comments INT(10) UNSIGNED NOT NULL,
	title VARBINARY(255) NOT NULL,
	content TEXT NOT NULL
);
 
INSERT INTO article(author_id,category_id,views,comments,title,content) 
VALUES(1,1,1,1,'1','1'),(2,2,2,2,'2','2'),(3,3,3,3,'3','3');

在没有创建索引的时候,使用explain查看执行计划

# 查询category_id=1 且comments>1的情况下,views最多的article_id
EXPLAIN 
SELECT id,author_id 
FROM article 
WHERE category_id=1 
AND comments>1 
ORDER BY views DESC 
LIMIT 1;

结论:type是ALL,最坏的情况,extra中出现了using filesort,也是最坏的情况,必须进行优化

#开始优化
#创建索引
#alter table article add index idx_article_ccv(category_id,comments,views);
CREATE INDEX idx_article_ccv ON article(category_id,comments,views);
 
#第二次explain
EXPLAIN 
SELECT id,author_id 
FROM article 
WHERE category_id=1 
AND comments>1 
ORDER BY views DESC 
LIMIT 1;

type变成了range,这是可以忍受的,但是extra里using filesort是无法接受的。

但是已经创建了索引,为什么没有用?因为按照Btree索引的工作原理,先降序category_id,如果遇到相同的category_id,再排序comments,如果遇到相同的comments,再排序views。

当comments字段在联合索引中处于中间位置时,因comments>1条件是一个范围值,故MySQL无法利用索引再对后面的views部分进行检索,即range类型查询字段后面的索引无效。

#删除第一次创建的索引
DROP INDEX idx_article_ccv ON article;
 
#第2次新建索引
CREATE INDEX idx_article_cv ON article(category_id,views);
 
#第3次explain
EXPLAIN 
SELECT id,author_id 
FROM article 
WHERE category_id=1 
AND comments>1 
ORDER BY views DESC 
LIMIT 1;

结论:type变成ref,extra中的using filesort也消失了,结果非常理想。

索引失效

以具体的案例说明失效的情况,首先先创建员工表和索引:

#创建员工表
CREATE TABLE staffs(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(24) NOT NULL DEFAULT "" COMMENT '姓名',
	age INT NOT NULL DEFAULT 0 COMMENT '年龄',
	pos VARCHAR(20) NOT NULL DEFAULT "" COMMENT '职位',
	add_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT'入职时间'
) CHARSET utf8 COMMENT '员工记录表';
 
INSERT INTO staffs(NAME,age,pos,add_time) VALUES('z3',22,'manager',NOW()),('july',23,'dev',NOW()),('2000',23,'dev',NOW());
 
 
#创建索引
ALTER TABLE staffs ADD INDEX idx_staffs_nameAgePos(NAME,age,pos);

1.联合索引(符合索引)不使用第一部分

创建联合索引,但是没有遵循最左前缀法则,则会出现索引失效的情况。

如果索引了多列,要遵守最左前缀法则。

指的是查询从索引的最左前列开始并且不跳过索引中的列。(带头大哥不能死,中间兄弟不能断哈哈哈)

2.where条件有数学运算或函数

3.mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描

4. mysql在使用 is null,is not null也无法使用索引

5. like以通配符开头(‘%abc…’)mysql索引失效会变成全表扫描的操作,当%加在右边时可以使用

6. 字符串不加单引号索引失效

7. where条件使用or

注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文