mysql 添加索引,ALTER TABLE和CREATE INDEX的区别 - Go语言中文社区

mysql 添加索引,ALTER TABLE和CREATE INDEX的区别


 

nvicat-->mysql表设计-->创建索引.

 

 

 

(1)使用ALTER TABLE语句创建索引,其中包括普通索引、UNIQUE索引和PRIMARY KEY索引3种创建索引的格式:

PRIMARY KEY 主键索引:mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 
NIQUE唯一索引:mysql>ALTER TABLE `table_name` ADD UNIQUE ( `column` ) 
INDEX普通索引 :mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) 
FULLTEXT全文索引 :mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`) 
INDEX多列索引:mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

索引名index_name可选,缺省时,MySQL将根据第一个索引列赋一个名称。另外,ALTER TABLE允许在单个语句中更改多个表,因此可以同时创建多个索引。

 


(2)使用CREATE INDEX语句对表增加索引。
能够增加普通索引和UNIQUE索引两种。其格式如下:
create index index_name on table_name (column_list) ;
create unique index index_name on table_name (column_list) ;  #表中有primary Key后不能用uniq index。
说明:table_name、index_name和column_list具有与ALTER TABLE语句中相同的含义,索引名不可选。另外,不能用CREATE INDEX语句创建PRIMARY KEY索引。


(3)删除索引。
删除索引可以使用ALTER TABLE或DROP INDEX语句来实现。2881064151DROP 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索引。
如果从表中删除某列,则索引会受影响。对于多列组合的索引,如果删除其中的某列,则该列也会从索引中删除。如果删除组成索引的所有列,则整个索引将被删除。
删除索引的操作,如下面的代码:
mysql> drop index shili on tpsc ;
Query OK, 2 rows affected (0.08 sec)
Records: 2 Duplicates: 0 Warnings: 0
该语句删除了前面创建的名称为“shili”的索引。

 

 

索引不一定是唯一所以,是可以加快查询速度的。

立索引原则:“如何查就如何建”。

索引的建立,唯一的原目的就是为了加快查询(广义的查询),实际上建立索引会使得数据存储所占空间变大,有时索引所占的空间会查过数据本身的空间。索引的建立也会使得数据插入时变慢,特殊情况下,慢的难以忍受,所以DBA的重要工作之一,就是检查索引层级并优化。

索引的目的就是希望尽可能的被索引的字段不重复,那么查找的效率就是1,如果完全重复,效率就是N,如果部分重复,那么效率会小于N,视重复量而定。mysql的索引算法是Btree。 

 

 

为什么重复值高的字段不能建索引(比如性别字段等) 

 

 结论(以innodb为例)

a、非聚簇索引存储了对主键的引用,如果select字段不在非聚簇索引内,就需要跳到主键索引(上图中从右边的索引树跳到左边的索引树),再获取select字段值

b、如果非聚簇索引值重复率高,那么查询时就会大量出现上图中从右边跳到左边的情况,导致整个流程很慢

c、如果where值重复率高的字段,select用了limit,只查较少数据,也就是跳的次数很少的情况下,还是可以建索引的(后来想想也没必要,limit限制了数量,全表扫描也很快,除非字段值是排序的,必须扫描完前面的所有值)

d、如果没有3这个前提,则不建议在值重复率高的字段上建索引,因为查询效率低,还需要维护索引

 

 

 

 

 

 

 

 

 

SQL有三个类型的索引,唯一索引 不能有重复,但聚集索引,非聚集索引可以有重复

重要:

(1) SQL如果创建时候,不指定类型那么默认是非聚集索引

(2) 聚集索引和非聚集索引都可以有重复记录,唯一索引不能有重复记录。

(3) 主键 默认是加了唯一约束的聚集索引,但是也可以在主键创建时,指定为唯一约束的非聚集索引,因此主键仅仅是默认加了唯一约束的聚集索引,不能说主键就是加了唯一约束的聚集索引

有点拗口,可以参考我的博客:主键就是聚集索引吗?

为列创建索引实际上就是为列进行排序,以方便查询.建立一个列的索引,就相当与建立一个列的排序。

    主键是唯一的,所以创建了一个主键的同时,也就这个字段创建了一个唯一的索引,

    唯一索引实际上就是要求指定的列中所有的数据必须不同。

    主键一唯一索引的区别:

         1 一个表的主键只能有一个,而唯一索引可以建多个。
         2 主键可以作为其它表的外键。
         3 主键不可为null,唯一索引可以为null。

聚集索引:将表内的数据按照一定的规则进行排列的目录。正因为如此,一个表中的聚焦索引只有一个。对此我们要注意“主键就是聚焦索引”这是极端错误的,是对聚焦索引的一种浪费。(虽然SQLServer默认主键就是聚焦索引)使用聚焦索引的最大好处就是按照查询要求,迅速缩小查询范围,避免进行全表扫描。其次让每个数目都不相同的字段作为聚焦索引也不符合“大数目不同情况下不应建立聚集索引的原则”。

一、索引的作用

1、帮助检索数据;

2、提高联接效率;

3、节省ORDER BY、GROUP BY的时间;

4、保证数据唯一性(仅限于唯一索引)。

 

二、索引的设计

在确定要建立一个索引时,首先我们要确定它是聚集还是非聚集、单列还是多列、唯一还是非唯一、列是升序还是降序、它的存储是如何的,比如:分区、填充因子等。下面逐条来看:

1、聚集索引

(1)首先指出一个误区,主键并不一定是聚集索引,只是在SQL SERVER中,未明确指出的情况下,默认将主键定义为聚集,而Oracle中则默认是非聚集,因为SQL SERVER中的ROWID未开放使用。

(2)聚集索引适合用于需要进行范围查找的列,因为聚集索引的叶子节点存放的是有序的数据行,查询引擎可根据WHERE中给出的范围,直接定位到两端的叶子节点,将这部分节点页的数据根据链表顺序取出即可;

(3)聚集索引尽量建立在值不会发生变更的列上,否则会带来非聚集索引的维护;

(4)尽量在建立非聚集索引之前建立聚集索引,否则会导致表上所有非聚集索引的重建;

(5)聚集索引应该避免建立在数值单调的列上,否则可能会造成IO的竞争,以及B树的不平衡,从而导致数据库系统频繁的维护B树的平衡性。聚集索引的列值最好能够在表中均匀分布。

3、唯一索引

(1)再指出一个误区,聚集索引并不一定是唯一索引,由于SQL SERVER将主键默认定义为聚集索引,事实上,索引是否唯一与是否聚集是不相关的,聚集索引可以是唯一索引,也可以是非唯一索引;

(2)将索引设置为唯一,对于等值查找是很有利的,当查到第一条符合条件的纪录时即可停止查找,返回数据,而非唯一索引则要继续查找,同样,由于需要保证唯一性,每一行数据的插入都会去检查重复性;

 

下面是一个简单的比较表

 

 

  主键 聚集索引
用途 强制表的实体完整性 对数据行的排序,方便查询用
一个表多少个 一个表最多一个主键 一个表最多一个聚集索引
是否允许多个字段来定义 一个主键可以多个字段来定义 一个索引可以多个字段来定义
     
是否允许 null 数据行出现 如果要创建的数据列中数据存在null,无法建立主键。
创建表时指定的 PRIMARY KEY 约束列隐式转换为 NOT NULL。
没有限制建立聚集索引的列一定必须 not null .
也就是可以列的数据是 null
参看最后一项比较
是否要求数据必须唯一 要求数据必须唯一 数据即可以唯一,也可以不唯一。看你定义这个索引的 UNIQUE 设置。
(这一点需要看后面的一个比较,虽然你的数据列可能不唯一,但是系统会替你产生一个你看不到的唯一列)
     
创建的逻辑 数据库在创建主键同时,会自动建立一个唯一索引。
如果这个表之前没有聚集索引,同时建立主键时候没有强制指定使用非聚集索引,则建立主键时候,同时建立一个唯一的聚集索引
如果未使用 UNIQUE 属性创建聚集索引,数据库引擎 将向表自动添加一个四字节 uniqueifier 列。
必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。
 

 

 

 

 

 

 

 

 

 

 

 

下面是更加详细的方法

MySQL中可以使用alter table这个SQL语句来为表中的字段添加索引。

使用alter table语句来为表中的字段添加索引的基本语法是:
ALTER TABLE <表名> ADD INDEX (<字段>);

我们来尝试为test中t_name字段添加一个索引。

mysql> alter table test add index(t_name);
Query OK, 0 rows affected (0.17 sec)
Records: 0  Duplicates: 0  Warnings: 0

执行成功后,我们来看看结果。

mysql> describe test;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| t_id       | int(11)     | YES  |     | NULL    |       |
| t_name     | varchar(50) | NO   | MUL | NULL    |       |
| t_password | char(32)    | YES  |     | NULL    |       |
| t_birth    | date        | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

结果可以看出,t_name字段的Key这一栏由原来的空白变成了MUL。这个MUL是什么意思呢?简单解释一下:如果Key是MUL,那么该列的值可以重复,该列是一个非唯一索引的前导列(第一列)或者是一个唯一性索引的组成部分但是可以含有空值NULL。


 

 

 

 

MySQL创建索引方法:ALTER TABLE和CREATE INDEX的区别

众所周知,MySQL创建索引有两种语法,即:
ALTER TABLE HeadOfState ADD INDEX (LastName, FirstName);
CREATE INDEX index_name HeadOfState (LastName, FirstName);
那么,这两种语法有什么区别呢? :wink:
在网上找了一下,在一个英文网站上,总结了下面几个区别,我翻译出来,如下:
1、CREATE INDEX必须提供索引名,对于ALTER TABLE,将会自动创建,如果你不提供;
2、CREATE INDEX一个语句一次只能建立一个索引,ALTER TABLE可以在一个语句建立多个,如:
      ALTER TABLE HeadOfState ADD PRIMARY KEY (ID), ADD INDEX (LastName,FirstName);
3、只有ALTER TABLE 才能创建主键,

英文原句如下:
With CREATE INDEX, we must provide a name for the index. With ALTER TABLE, MySQL creates an index name automatically if you don’t provide one.Unlike ALTER TABLE, the CREATE INDEX statement can create only a single index per statement. In addition, only ALTER TABLE supports the use of PRIMARY KEY.

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_34128237/article/details/86346667
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-28 02:52:41
  • 阅读 ( 1264 )
  • 分类:数据库

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢