0
点赞
收藏
分享

微信扫一扫

mysql -- 索引

影子喵喵喵 2022-04-07 阅读 38
python

定义

对数据库表的一列或多列的值进行排序的一种数据结构。

优点

加快数据检索速度

缺点

占用物理存储空间(/var/lib/mysql)

当对表中数据更新时,索引需要动态维护,降低数据维护速度

索引示例:

# cursor.executemany(SQL, [data1, data2, data3])

# 以次IO执行多条表记录操作,效率高,节省资源

数据库准备:

在mysql客户端创建一个数据库

 CREATE TABLE `student` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `age` int unsigned DEFAULT NULL,
  `password` char(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

用以下python脚本向这个数据库中插入1百万条数据:

import pymysql
import random

alpha = "abcdefghijklmnopqrstuvwxrz";
password = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.-+_[]<>"

#

class Studinfo:     
# 返回一个三个元素组成的元组(name, age, password)
# name: 4~8字符组成
# age:取值10~20
# password:8个字符长度
    @staticmethod
    def get_info():

        length = random.randint(4, 8)
        name = ""
        for i in range(length):
            index = random.randint(0, len(alpha) - 1)
            if i == 0:
                name += alpha[index].upper()
            else:
                name += alpha[index]

        pwd = ""
        for i in range(8):
            index = random.randint(0, len(password) - 1)
            pwd += password[index]

        age = random.randint(10, 20)

        return name, age, pwd


db = pymysql.connect(host='192.168.1.10',
                     port=3306,
                     user='dbuser',
                     password='abcdef12345',
                     database='student',
                     charset="utf8mb4")

# 获取游标(操作数据库, 执行sql语句)
cur = db.cursor()

sqlpattern = 'insert into student (name, age,password) values ("%s", %d,"%s");'

for i in range(1000000):
    sql = sqlpattern % Studinfo.get_info()
    print(sql)
    cur.execute(sql)
    if i % 100 == 0:
        db.commit()

db.commit()

cur.close()
db.close()

执行以上python脚本后,查看数据库中student数据表的数据记录数目:

mysql> select count(*) from student;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+
1 row in set (0.13 sec)

索引测试:

1、开启运行时间检测:

mysql> show variables like 'profil%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| profiling              | OFF   |
| profiling_history_size | 15    |
+------------------------+-------+
2 rows in set (0.00 sec)

mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show variables like 'profil%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| profiling              | ON    |
| profiling_history_size | 15    |
+------------------------+-------+
2 rows in set (0.00 sec)

2、执行没有建立索引时的查询语句,查询需要0.32636350秒:

mysql> select * from student where name='Sqwxbm';
+--------+--------+------+----------+
| id     | name   | age  | password |
+--------+--------+------+----------+
| 900000 | Sqwxbm |   14 | jO,Ak>uv |
+--------+--------+------+----------+
1 row in set (0.36 sec)

mysql> show profiles;
+----------+------------+-------------------------------------------+
| Query_ID | Duration   | Query                                     |
+----------+------------+-------------------------------------------+
|        1 | 0.00207250 | show variables like 'profil%'             |
|        2 | 0.01848775 | drop index
 name on student              |
|        3 | 0.33722400 | select * from student where name='Sqwxbm' |
|        4 | 0.32636350 | select * from student where name='Sqwxbm' |
+----------+------------+-------------------------------------------+
4 rows in set, 1 warning (0.00 sec)

3、在name字段创建索引,并进行相同的查询测试,查询时间为0.00046925秒:

mysql> create index idx_name on student(name);
Query OK, 0 rows affected (7.61 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select * from student where name='Sqwxbm';
+--------+--------+------+----------+
| id     | name   | age  | password |
+--------+--------+------+----------+
| 900000 | Sqwxbm |   14 | jO,Ak>uv |
+--------+--------+------+----------+
1 row in set (0.00 sec)

mysql> show profiles;
+----------+------------+-------------------------------------------+
| Query_ID | Duration   | Query                                     |
+----------+------------+-------------------------------------------+
|        1 | 0.00207250 | show variables like 'profil%'             |
|        2 | 0.01848775 | drop index
 name on student              |
|        3 | 0.33722400 | select * from student where name='Sqwxbm' |
|        4 | 0.32636350 | select * from student where name='Sqwxbm' |
|        5 | 7.61299850 | create index idx_name on student(name)    |
|        6 | 0.00046925 | select * from student where name='Sqwxbm' |
|        7 | 0.00011975 | show proifles                             |
+----------+------------+-------------------------------------------+
7 rows in set, 1 warning (0.00 sec)

索引类型

普通(MUL)和唯一(UNI)

使用规则

1、可设置多个字段

2、普通索引:字段值无约束,KEY标志位MUL

3、唯一索引:字段值不允许重复,字段值可为NULL,KEY标志位UNI

4、哪些字段创建索引:经常查询的字段、where条件判断字段、order by排序字段

创建普通索引和唯一索引

1、创建表时

CREATE TABLE 表名(

字段名 数据类型,

字段名 数据类型,

index(字段名),

index(字段名),

unique(字段名)

);

示例:创建一个数据表,由三个字段组成,id为主键、自增;name为普通索引;phone为唯一索引

mysql> create table stu1(
    -> id int primary key auto_increment,
    -> name varchar(30) not null,
    -> phone varchar(11) not null,
    -> index(name),
    -> unique(phone)
    -> )engine=innodb charset=utf8mb4;
Query OK, 0 rows affected (0.06 sec)

mysql> desc stu1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | NO   | MUL | NULL    |                |
| phone | varchar(11) | NO   | UNI | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> insert into stu1 (name, phone) values ('zhangsan','13711111111');
Query OK, 1 row affected (0.01 sec)

mysql> insert into stu1 (name, phone) values ('zhangsan','13711111112');
Query OK, 1 row affected (0.01 sec)

mysql> insert into stu1 (name, phone) values ('lisi','13711111112');
ERROR 1062 (23000): Duplicate entry '13711111112' for key 'stu1.phone'

2、已有表中创建索引:

create [unique] index 索引名 on 表名(字段名)

示例:创建一个数据表,由三个字段组成,然后为其name字段添加普通索引,为phone字段添加唯一索引

mysql> create table stu2(
    -> id int primary key auto_increment,
    -> name varchar(30) not null,
    -> phone char(11) not null)engine=innodb charset=utf8mb4;
Query OK, 0 rows affected (0.05 sec)

mysql> desc stu2;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | NO   |     | NULL    |                |
| phone | char(11)    | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> create index idx_name on stu2(name);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> create unique index indx_phone on stu2(phone);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc stu2;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | NO   | MUL | NULL    |                |
| phone | char(11)    | NO   | UNI | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

查看索引:

1、desc 表名;   ---> KEY标识为:MUL UNI

mysql> desc stu2;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | NO   | MUL | NULL    |                |
| phone | char(11)    | NO   | UNI | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

2、show index from 表名\G;

mysql> show index from stu2\G;
*************************** 1. row ***************************
        Table: stu2
   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:
      Visible: YES
   Expression: NULL
*************************** 2. row ***************************
        Table: stu2
   Non_unique: 0
     Key_name: indx_phone
 Seq_in_index: 1
  Column_name: phone
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
      Visible: YES
   Expression: NULL
*************************** 3. row ***************************
        Table: stu2
   Non_unique: 1
     Key_name: idx_name
 Seq_in_index: 1
  Column_name: name
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
      Visible: YES
   Expression: NULL
3 rows in set (0.00 sec)

删除索引:

drop index 索引名 on 表名

示例:删除stu2表上字段name和phone上的索引

mysql> drop index idx_name on stu2;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> drop index indx_phone on stu2;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc stu2;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | NO   |     | NULL    |                |
| phone | char(11)    | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

主键(PRI)和自增长(AUTO_INCREMENT)

使用规则

  1. 一个表只能有一个主键字段
  2. 所带约束:不允许重复,且不能为空
  3. KEY标志(primary): PRI
  4. 通常设置记录编号字段id,能唯一索引一条记录

创建

创建表时添加主键

create table 表名(

字段1 int auto_increment,

....

primary key(字段1)

)auto_increment=起始值; ## 设置自增和起始值

示例:

mysql> create table stu3(
    -> id int auto_increment,
    -> name varchar(30) not null,
    -> primary key(id)
    -> )engine=innodb charset=utf8mb4 auto_increment=10000;
Query OK, 0 rows affected (0.04 sec)

mysql> desc stu3 ;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> select * from stu3;
+-------+----------+
| id    | name     |
+-------+----------+
| 10000 | zhangsan |
| 10001 | lisi     |
+-------+----------+
2 rows in set (0.00 sec)

已有表添加主键

alter table 表名 add primay key(id)

示例:

mysql> create table stu4(
    -> id int,
    -> name varchar(30)
    -> )engine=innodb charset=utf8mb4;
Query OK, 0 rows affected (0.04 sec)

mysql> alter table stu4 add primary key(id);
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

已有表操作自增长属性

1、已有表增加自增长属性:alter table 表名 moidfy id int auto_increment;

mysql> create table stu5(
    -> id int,
    -> name varchar(30)
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> create index idx_id on stu5(id);    //在stu5表的id字段上添加索引
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table stu5 modify id int auto_increment;  //修改id字段为自增
Query OK, 0 rows affected (0.10 sec)
Records: 0  Duplicates: 0  Warnings: 0

2、已有表重新指定起始值:alter table 表名 auto_increment=20000;

mysql> alter table stu5 auto_increment=20000;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

删除

1、删除自增长属性(modify):alter table 表名 id int;

mysql> create table stu6(
    -> id int auto_increment,
    -> name varchar(30),
    -> primary key(id)
    -> )auto_increment=20000;
Query OK, 0 rows affected (0.04 sec)

mysql> alter table stu6 modify id int;
Query OK, 0 rows affected (0.14 sec)
Records: 0  Duplicates: 0  Warnings: 0

2、删除主键索引:alter table 表名 drop primary key;

mysql> alter table stu6 drop primary key;
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc stu6;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   |     | NULL    |       |
| name  | varchar(30) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
举报

相关推荐

0 条评论