zoukankan      html  css  js  c++  java
  • MySQL之索引操作

    一、什么是索引

    索引就像是书籍的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时可以加快查询速度。常用的索引有:

    • 主键索引
    • 普通索引
    • 联合索引
    • 唯一索引

    二、索引的使用

    (一)主键索引

    查询数据库时,按照主键索引是最快的,主键是唯一的。在创建主键索引时,有两种情况:

    1、建表时创建

    在创建表时可以创建主键索引。

    mysql> create table userinfo(
        -> id int(4) not null auto_increment,
        -> username varchar(32) default null,
        -> age tinyint(2) not null default 0,
        -> primary key(id)
        -> );
    Query OK, 0 rows affected (0.01 sec)

    通过primary key和auto_increment来创建主键。创建后可以通过desc命令查看:

    mysql> desc userinfo;
    +----------+-------------+------+-----+---------+----------------+
    | Field    | Type        | Null | Key | Default | Extra          |
    +----------+-------------+------+-----+---------+----------------+
    | id       | int(4)      | NO   | PRI | NULL    | auto_increment |
    | username | varchar(32) | YES  |     | NULL    |                |
    | age      | tinyint(2)  | NO   |     | 0       |                |
    +----------+-------------+------+-----+---------+----------------+
    3 rows in set (0.00 sec)

    2、建表后增加

    假如现在的表没有主键,建表语句如下:

    create table userinfo(
        id int(4) not null,
        username varchar(32) default null,
        age tinyint(2) not null default 0
    );
    View Code

    现在增加主键:

    mysql> alter table userinfo change id id int primary key auto_increment;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    (二)普通索引

    普通索引可以创建多个,它唯一的作用就是加快查询速度,它的创建修改如下:

    1、建表时创建

    mysql> create table userinfo(
        -> id int(4) not null auto_increment,
        -> username varchar(32) default null,
        -> age tinyint(2) not null default 0,
        -> primary key(id),
        -> KEY index_name(username)
        -> );
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> desc userinfo;
    +----------+-------------+------+-----+---------+----------------+
    | Field    | Type        | Null | Key | Default | Extra          |
    +----------+-------------+------+-----+---------+----------------+
    | id       | int(4)      | NO   | PRI | NULL    | auto_increment |
    | username | varchar(32) | YES  | MUL | NULL    |                |
    | age      | tinyint(2)  | NO   |     | 0       |                |
    +----------+-------------+------+-----+---------+----------------+
    3 rows in set (0.01 sec)

    在建表时使用KEY index_name(column)来创建普通索引,注意的是在唯一值多的列上创建索引查询效率更高。

    2、建表后增加

    -- 删除索引
    mysql> alter table userinfo drop index index_name;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    -- 查看
    mysql> desc userinfo;
    +----------+-------------+------+-----+---------+----------------+
    | Field    | Type        | Null | Key | Default | Extra          |
    +----------+-------------+------+-----+---------+----------------+
    | id       | int(4)      | NO   | PRI | NULL    | auto_increment |
    | username | varchar(32) | YES  |     | NULL    |                |
    | age      | tinyint(2)  | NO   |     | 0       |                |
    +----------+-------------+------+-----+---------+----------------+
    3 rows in set (0.04 sec)
    
    -- 添加索引
    mysql> alter table userinfo add index index_username(username);
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    3、对字段的前n个字符创建普通索引

       当表中的列的内容比较多时,并且列的内容的前n个字符已经接近唯一时,可以对列的前n个字符建立索引,而无需对整个列建立索引,这样可以节省创建索引占用的系统空间,以及降低读取和更新维护索引消耗的资源。

    -- 创建索引的语法
    create index index_name on userinfo(username(5))
    
    -- 创建实例
    mysql> create index index_username on userinfo(username(5));
    Query OK, 0 rows affected (0.03 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    -- 查看索引
    mysql> show index from userinfoG;
    *************************** 1. row ***************************
            Table: userinfo
       Non_unique: 0
         Key_name: PRIMARY
     Seq_in_index: 1
      Column_name: id
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null: 
       Index_type: BTREE
          Comment: 
    Index_comment: 
    *************************** 2. row ***************************
            Table: userinfo
       Non_unique: 1
         Key_name: index_username
     Seq_in_index: 1
      Column_name: username
        Collation: A
      Cardinality: 0
         Sub_part: 5
           Packed: NULL
             Null: YES
       Index_type: BTREE
          Comment: 
    Index_comment: 
    2 rows in set (0.00 sec)

    (三)联合索引

    如何表中有多个列,可以基于这多个列创建联合索引:

    • 基于多列创建联合索引
    • 基于多列的前n个字符创建联合索引

    1、基于多列创建联合索引

    -- 删除之前的普通索引
    mysql> drop index index_username on userinfo;
    Query OK, 0 rows affected (0.04 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    -- 创建联合索引
    mysql> create index index_username_age on userinfo(username,age);
    Query OK, 0 rows affected (0.05 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    -- 查看索引
    mysql> show index from userinfoG;
    *************************** 1. row ***************************
            Table: userinfo
       Non_unique: 0
         Key_name: PRIMARY
     Seq_in_index: 1
      Column_name: id
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null: 
       Index_type: BTREE
          Comment: 
    Index_comment: 
    *************************** 2. row ***************************
            Table: userinfo
       Non_unique: 1
         Key_name: index_username_age
     Seq_in_index: 1
      Column_name: username
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null: YES
       Index_type: BTREE
          Comment: 
    Index_comment: 
    *************************** 3. row ***************************
            Table: userinfo
       Non_unique: 1
         Key_name: index_username_age
     Seq_in_index: 2
      Column_name: age
        Collation: A
      Cardinality: 0
         Sub_part: NULL
           Packed: NULL
             Null: 
       Index_type: BTREE
          Comment: 
    Index_comment: 
    3 rows in set (0.01 sec)

     2、基于多列的前n个字符创建联合索引

    -- 删除联合索引
    mysql> drop index index_username_age on userinfo;
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    -- 创建联合索引
    mysql> create index index_username_age on userinfo(username(5),age(1));
    Query OK, 0 rows affected (0.01 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    3、创建表时创建

    create table userinfo(
        id int(4) not null auto_increment,
        username varchar(32) default null,
        age tinyint(2) not null default 0,
        primary key(id),
        KEY index_name(username,age)
    );

    注意的是按条件列查询数据时,联合索引是有前缀生效特性的,列入index(col1,col2,col3)是col1或者col1,col2或者col1,col2,col3生效,其余的比如col2,col3等不生效。

    (四)唯一索引

    如果想创建某列或者几列的值是唯一的,那么可以创建唯一非主键索引。

    --  创建唯一非主键索引
    mysql> create unique index index_uni_username on userinfo(username);
    Query OK, 0 rows affected (0.02 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    
    --  查看表结构
    mysql> desc userinfo;
    +----------+-------------+------+-----+---------+----------------+
    | Field    | Type        | Null | Key | Default | Extra          |
    +----------+-------------+------+-----+---------+----------------+
    | id       | int(4)      | NO   | PRI | NULL    | auto_increment |
    | username | varchar(32) | YES  | UNI | NULL    |                |
    | age      | tinyint(2)  | NO   |     | 0       |                |
    +----------+-------------+------+-----+---------+----------------+
    3 rows in set (0.00 sec)

    三、总结

    (一)索引的创建与生效条件

      索引虽然可以加快查询速度,但是并非可以将所有的列都加上索引。因为索引不但占用系统空间,而且在更新数据库时还需要维护索引数据。所以对于小表(几百行)以及读取少,写的多的业务没有必要建立索引。

      对于select username,age where id = ...这样的语句,索引列应该建立在where语句后的列上,而非建立在select这样的查询列上。另外就是尽量将索引建立在唯一值多的列上面。

    (二)创建索引的命令

    -- create或者alter均可
    
    -- 创建主键索引
    alter table userinfo change id id int primary key auto_increment
    -- 删除主键索引
    alter table userinfo drop primary key
    
    -- 创建普通索引
    alter table userinfo add index index_username(username)
    -- 根据列前n个字符创建普通索引
    create index index_username on userinfo(username(5))
    -- 删除普通索引
    alter table userinfo drop index index_username
    drop index index_username on userinfo
    
    -- 根据多个列创建联合索引
    create index index_username_age on userinfo(username,age)
    -- 根据多个列前n个字符创建联合索引
    create index index_username_age on userinfo(username(5),age(1))
    
    -- 创建唯一索引
    create unique index index_uni_username on userinfo(username)
  • 相关阅读:
    IO流
    集合中的工具类Collections和Arrays
    排序 查找
    函数及数组
    变量、静态的和单例模式
    java流程控制
    configure使用
    --sysroot
    LD_PRELOAD
    Linux下内存检测工具:asan :编译-连接-运行选项
  • 原文地址:https://www.cnblogs.com/shenjianping/p/13532580.html
Copyright © 2011-2022 走看看