MySQL的索引

1、索引的概述
索引是一种将数据库中单列或者多列的值进行排序的结构。应用良好的索引可以提高查询速度,降低服务器的负载;提高数据库系统的整体性能。但是,创建索引和维护需要耗费时间,索引也需要占用物理空间,会给数据的维护带来一些麻烦。
不同的存储引擎定义每个表的最大索引数和最大索引长度。所有存储引擎对每个表至少支持16个索引。总索引长度至少为256个字节。有些存储引擎支持更多的索引数和更大的索引长度。索引有两种存储类型,包括B树(BTREE)索引和哈希(HASH)索引。其中,B树索引为系统默认索引。

2、索引的分类
1)普通索引
即不应用任何限制条件的索引,该索引可以在任何数据类型中创建。字段本身的约束条件可以判断其值是否为空或唯一。创建该类型索引后,用户在查询时,便可以通过索引进行查询。在某数据表的某一字段中,建立普通索引后。用户需要查询数据时,只需根据该索引进行查询便可。
创建普通索引:
方法一:

MariaDB [aaa]> create table test1(id int(10) not null,name char(20) not null,age int(10) not null,index (id));
Query OK, 0 rows affected (0.13 sec)

MariaDB [aaa]> 
MariaDB [aaa]> show create  table test1\G;
*************************** 1. row ***************************
       Table: test1
Create Table: CREATE TABLE `test1` (
  `id` int(10) NOT NULL,
  `name` char(20) NOT NULL,
  `age` int(10) NOT NULL,
  KEY `id` (`id`)               //创建该表索引为id列
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 

查看数据是否从索引获取:

MariaDB [aaa]> insert into test1  values(1,'xiaoming',10),(2,'xiaohong',11),(3,'xiaodong',12);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

MariaDB [aaa]> 
MariaDB [aaa]> 
MariaDB [aaa]> select * from test1;
+----+----------+-----+
| id | name     | age |
+----+----------+-----+
|  1 | xiaoming |  10 |
|  2 | xiaohong |  11 |
|  3 | xiaodong |  12 |
+----+----------+-----+
3 rows in set (0.00 sec)

MariaDB [aaa]> show indexes from test1\G;             //查看该表的索引信息
*************************** 1. row ***************************
        Table: test1
   Non_unique: 1
     Key_name: id
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 3
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 
MariaDB [aaa]> explain select * from test1 where id=3\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test1
         type: ref
possible_keys: id
          key: id
      key_len: 4
          ref: const
         rows: 1               //此时数据走索引只检索了一行
        Extra: 
1 row in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 

删除索引再试试:

MariaDB [aaa]> drop index id on test1;             //删除表中的id索引列
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [aaa]> 
MariaDB [aaa]> show index from test1\G;        //此时再看表中已经没有索引字段了
Empty set (0.00 sec)

MariaDB [aaa]> explain select * from test1 where id=3 \G;            //再次查看id为3的字段
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test1
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3                   //此时检索了表的三个字段,比没有索引更加消耗服务器资源
        Extra: Using where
1 row in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 

方法二:

MariaDB [aaa]> create index age_inx on test1(age);        //创建一个名称为agx_inx的age字段的索引
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [aaa]> show index from test1\G;                 //查看表中的索引
*************************** 1. row ***************************
        Table: test1
   Non_unique: 1
     Key_name: age_inx
 Seq_in_index: 1
  Column_name: age
    Collation: A
  Cardinality: 3
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.01 sec)

ERROR: No query specified
MariaDB [aaa]> explain select * from test1  where age=12\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test1
         type: ref
possible_keys: age_inx
          key: age_inx
      key_len: 4
          ref: const
         rows: 1
        Extra: 
1 row in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 

删除该索引:

MariaDB [aaa]> drop index age_inx on test1;
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [aaa]> 

方法三:

MariaDB [aaa]> alter table test1 add index id_inx(id);              //添加一个名称为id_inx的id字段的索引
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [aaa]> show index from test1\G;             //查看表中的索引
*************************** 1. row ***************************
        Table: test1
   Non_unique: 1
     Key_name: id_inx
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 3
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 

2)唯一性索引
使用UNIQUE参数可以设置唯一索引。创建该索引时,索引的值必须唯一,通过唯一索引,用户可以快速定位某条记录,主键是一种特殊唯一索引。

MariaDB [aaa]> create unique index age_inx on test1(age);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [aaa]> show index from test1\G;
*************************** 1. row ***************************
        Table: test1
   Non_unique: 0
     Key_name: age_inx
 Seq_in_index: 1
  Column_name: age
    Collation: A
  Cardinality: 3
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 

3)全文索引
使用FULLTEXT参数可以设置索引为全文索引。全文索引只能创建在CHAR、VARCHAR或者TEXT类型的字段上。查询数据量较大的字符串类型的字段时,使用全文索引可以提高查询速度。例如,查询带有文章回复内容的字段,可以应用全文索引的方式。需要注意的是,在默认情况下,应用全文索引搜索大小写不敏感。如果索引的列使用二进制排序后,可以执行大小写敏感的全文索引。只有MyISAM类型的数据表支持FULLTEXT全文索引,InnoDB或者其他类型的数据表不支持全文索引。

4)单列索引
单列索引即只对应一个字段的索引。其可以包括上述叙述的3种索引方式。应用该索引条件只需要保证该索引值对应一个字段即可。

5)多列索引
多列索引是在表的多个字段上创建索引。该索引指向创建时对应的多个字段,用户可以通过这几个字段进行查询。要想应用该索引,用户必须使用这些字段中的第一个字段。触发多列索引的条件是用户必须使用索引的第一字段,如果没有用到第一字段,则索引不起任何作用,用户想要优化查询速度,可以应用该类索引形式。

MariaDB [aaa]> create index inx_id_age on test1(id,age);     //创建一个名称为inx_id_age的id字段和age字段的所有
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [aaa]> show index from test1\G;         //查看表中的索引
*************************** 1. row ***************************
        Table: test1
   Non_unique: 1
     Key_name: inx_id_age
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 3
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
*************************** 2. row ***************************
        Table: test1
   Non_unique: 1
     Key_name: inx_id_age
 Seq_in_index: 2
  Column_name: age
    Collation: A
  Cardinality: 3
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
2 rows in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 

测试不查询第一个字段是否会走索引:

MariaDB [aaa]> explain select * from test1 where age=2\G;          //只查询age字段
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test1
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3                   //并没有走索引
        Extra: Using where
1 row in set (0.00 sec)

ERROR: No query specified

MariaDB [aaa]> 
MariaDB [aaa]> explain select * from test1 where id=2 \G;       //只查询id字段
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test1
         type: ref
possible_keys: inx_id_age
          key: inx_id_age
      key_len: 4
          ref: const
         rows: 1              //有走索引
        Extra: 
1 row in set (0.01 sec)

ERROR: No query specified

MariaDB [aaa]> 
MariaDB [aaa]> explain select * from test1 where id=3 and age=3 \G;       //查询两个字段
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test1
         type: ref
possible_keys: inx_id_age
          key: inx_id_age
      key_len: 8
          ref: const,const
         rows: 1                        //同样有走索引
        Extra: 
1 row in set (0.00 sec)

ERROR: No query specified

提示:按条件列查询数据时,联合索引是有前缀生效特性的。
index(a,b,c)仅a,ab,abc三个查询条件可以走索引。b,bc,ac,c等无法使用索引了。

6)空间索引
使用SPATIAL参数可以设置索引为空间索引。空间索引只能建立在空间数据类型上,这样可以提高系统获取空间数据的效率。MySQL中只有MyISAM存储引擎支持空间检索,而且索引的字段不能为空值。

索引列的创建及生效条件:
1) 因为索引不但占用系统空间,更新数据库时还需要维护索引数据的,因此索引是一把双刃剑,并不是越多越好,例如:数十到几百行的小表上无需建立索引,更新频繁,读取比较少的表要少去建立索引。索引不是越多越好。
2) 需要在哪些列上创建索引呢?
例如:select user,host from mysql.user where host=…,索引一定要创建在where后条件列上,而不是select后的选择的数据的列。另外,我们要尽量选择在唯一值多的大表上的列建立索引。要在表的列上创建索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值