详解 MySQL 中的字段索引和主键 - 文章教程

详解 MySQL 中的字段索引和主键

发布于 2020-03-23 字数 5874 浏览 1038 评论 0

索引的类型

  • UNIQUE 唯一索引:不可以出现相同的值,可以有NULL值
  • INDEX 普通索引:允许出现相同的索引内容
  • PROMARY KEY 主键索引:不允许出现相同的值
  • fulltext index 全文索引:可以针对值中的某个单词,但效率确实不敢恭维
  • 组合索引:实质上是将多个字段建到一个索引里,列值的组合必须唯一

一张表中只能有一个主键

  • 一个主键可以指向多列,叫做复合主键;
  • 主键索引应该给 ID,并且 ID 自增;
  • 主键索引效率最高,不能为空,不能重复;

设置复合主键

方法一:在建表时就写出

Create Table 表名 (
 字段名1 Int Not Null,
 字段名2 nvarchar(13) Not Null Primary Key (字段名1, 字段名2),
 字段名3…………,
 字段名N…………
)

方法二:在建表后更改

ALTER TABLE 表名 WITH NOCHECK ADD
CONSTRAINT [PK_表名] PRIMARY KEY NONCLUSTERED(
  [字段名1],
  [字段名2]
)

索引的创建

创建表的时候同时创建索引

CREATE TABLE `table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
  `time` int(10) NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  INDEX index_name (title(length)
)

修改表结构的方式添加索引

ALTER TABLE 表名 ADD 索引类型 (unique,primary key,fulltext,index)[索引名](字段名)

普通索引

alter table table_name add index index_name (column_list) ;

唯一索引

alter table table_name add unique (column_list) ;

主键索引

alter table table_name add primary key (column_list) ;
CREATE INDEX index_name ON table_name(username(length));

create 只能添加这两种索引;

CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)

索引查询

desc table_name;
show keys from table_name;
show index from table_name;
show indexs from table_name;

删除索引

删除索引可以使用 ALTER TABLE 或 DROP INDEX 语句来实现。

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

注意事项

1.索引不会包含有NULL的列

只要列中包含有NULL值,都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此符合索引就是无效的。

2.使用短索引

对串列进行索引,如果可以就应该指定一个前缀长度。例如,如果有一个char(255)的列,如果在前10个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

3.索引列排序

mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列建复合索引。

4.like 语句操作

一般情况下不鼓励使用like操作,如果非使用不可,注意正确的使用方式。like ‘%aaa%’和 ‘%aaa’不会使用索引,只有like ‘aaa%’可以使用索引。

5.不要在列上进行运算

6.不使用复杂的操作

NOT IN 、<>、!= 操作,但 <,<=,=,>,>=,BETWEEN,IN 是可以用到索引的

7.索引要建立在经常进行select操作的字段上。

这是因为,如果这些列很少用到,那么有无索引并不能明显改变查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。

8.索引要建立在值比较唯一的字段上。

9.选择合适的字段类型

对于那些定义为text、image和bit数据类型的列不应该增加索引。因为这些列的数据量要么相当大,要么取值很少。

10.在where和join中出现的列需要建立索引。

11.where的查询条件里有不等号(where column != …),mysql将无法使用索引。

12.如果where字句的查询条件里使用了函数(如:where DAY(column)=…),mysql将无法使用索引。

13.在join操作中(需要从多个数据表提取数据时),mysql只有在主键和外键的数据类型相同时才能使用索引,否则及时建立了索引也不会使用。

14.对于多列索引,只要查询语句使用到了左边的列,就会用到索引,否则不会用到索引。

15.对于’or’ sql语句,必须所有的被查询的列都建有索引,才会用到索引。

16.如果被查询的列的类型是字符串,则需要在语句中对数据添加引号,比如:

select * from emp where ename='1111';

不能是

select * from emp where ename=1111;

索引的使用情况查询

查看索引的使用情况

show status like 'Handler_read%'

大家注意:

  • Handler_read 这个值越高越好,越高表示使用索引查询的次数越多
  • Handler_read_rnd_next 这个值越高,说明查询低效

全文检索

LIKE 搜索

SELECT body FROM table_name WHERE body LIKE "%random_word1%" AND bodyLIKE "% random_word2%" AND body LIKE "% random_word3%";

FULLTEXT 搜索

SELECT body FROM table_name WHERE MATCH(body) AGAINST("+random_word3 + random_word3+ random_word3" IN BOOLEAN MODE)

结果讨论

LIKE 搜索的耗时随着记录数的增加而线性增长,但对于10万行记录以下的表(这里共100000*50个单词)搜索时间基本上能保持在1秒以内,所以 like 搜索的性能也不是特别差。由不同词汇量生成的文本对 LIKE 搜索的性能影响不大,不同词汇量对应的搜索时间基本上在一个很小的时间范围内变化。

FULLTEXT 搜索耗时也随表中记录数的增长而线性增加。对于 10 万行记录以下的表(这里共100000*50个单词)搜索时间基本上能保持在0.01秒以内。由不同词汇量生成的随机文本对FULLTEXT搜索性能有相对来说比较显著的影响。每行记录中含同样的单词数,这样,较大的词汇量倾向于生成冗余度更低的文本,相应的搜索耗时倾向于更少。这可能与FULLTEXT索引建立单词索引的机制有关,较大的词汇量倾向于生成范围广但相对较浅的索引,因而能快速确定文本是否匹配。

与 LIKE 搜索相比,FULLTEXT 全文搜索的性能要强很多,对于 10 万行记录的表,搜索时间都在 0.02 秒以下。因此可以将基于 FULLTEXT 索引的文本搜索部署于网站项目中的文本搜索功能中。但是正如上述提到的,无论是 LIKE 搜索还是 FULLTEXT 搜索,其性能都会随着记录数的增长而下降,因此若网站项目中的文本搜索数据库记录数庞大的一定规模后,可能需要考虑使用 MySQL 数据库全文搜索以外的文本搜索解决方案了。

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

2583 文章
29 评论
84935 人气
更多

推荐作者

猫性小仙女

文章 1 评论 0

qq_VO6LhT

文章 0 评论 0

猿舌电影

文章 0 评论 0

7556275422

文章 0 评论 0

YYQ_139

文章 0 评论 0