mysql测试索引在表中的作用

实验内容

单表中的索引使用

1.建表

create table t_book(id int,a1 varchar(200),a2 varchar(200),a3 varchar(200),a4 varchar(200),a5 varchar(200),a6 varchar(200),a7 varchar(200),a8 varchar(200),a9 varchar(200))

2.写存储过程向表中插入较大数据//或其他方式使数据增大

(1)绑定变量:

PREPARE stmt1 FROM ‘insert into t_book(id,a1,a2,a3,a4,a5,a6,a7,a8,a9)values(?,?,?,?,?,?,?,?,?,?)‘;

(2)存储过程创建:

delimiter ||

create procedure pro1()

begin

set

@a=‘aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa‘;

set @i=0;

while @i<10000 do

EXECUTE stmt1 USING @i,@a,@a,@a,@a,@a,@a,@a,@a,@a;

    set @i=@i+1;

 end while;

 end;||

delimiter ;

执行存储过程

Call pro1()

3.记录select查询所用时间 time1

SELECT * FROM t_book WHERE id =1; 

4.用explain关键字查看此语句的执行计划

explain SELECT * FROM t_book WHERE id =1; 

5.在已有表t_book创建主键 id;

ALTER TABLE t_book ADD CONSTRAINT pk_book PRIMARY KEY(id); 

6. 记录select查询所用时间 time2

SELECT * FROM t_book WHERE id =1;

7.用explain关键字查看此语句的执行计划,并记录

explain SELECT * FROM t_book WHERE id =1; 

8.比较两次执行计划的区别,并比较time1和time2

多表连接中索引使用

1.建表t_book1,t_book2(其中列与单表实验中t_book相同)

2.写存储过程,分别向两表中插入较大数据//或其他方式使数据增大(像单表实验中一样)

3.SELECT * FROM t_book1,t_book2 WHERE t_book1.id =t_book2.id AND t_book1.id=10; 记录查询所用时间 time1

4.用explain关键字查看此语句的执行计划,并记录

5.在两表上分别创建主键 id;

6.SELECT * FROM t_index WHERE t_book1.id =t_book2.id; 记录查询所用时间 time2

7.用explain关键字查看此语句的执行计划,并记录

8.比较两次执行计划的区别,并比较time1和time2,体会索引在查询中的作用

背景知识

1.主键的创建

(1)创建主键语法
ALTER TABLE table_name ADD CONSTRAINT pk_name PRIMARY KEY(列名);

(2)创建外键语法

ALTER TABLE news_info[子表名] ADD CONSTRAINT
FK_news_info_news_type[约束名] FOREIGN KEY (info_id)[子表列] REFERENCES news_type[主表名] (id)[主表列] ;

(3)使用组合主键

如果一列不能唯一区分一个表里的记录时,可以考虑多个列组合起来达到区分表记录的唯一性,形式

①创建时:create table sc (
studentno int,
courseid int,
score int,
primary key (studentno,courseid) );
②修改时:alter
table tb_name add primary key (字段1,字段2,字段3);

2.explain语句

explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。

使用方法,在select语句前加上explain就可以了:

如:

explain select surname,first_name form a,b where a.id=b.id

EXPLAIN列的解释:

table:显示这一行的数据是关于哪张表的

type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL

possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句

key: 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE
INDEX(indexname)来强制使用一个索引或者用IGNORE
INDEX(indexname)来强制MYSQL忽略索引

key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数

rows:MYSQL认为必须检查的用来返回请求数据的行数

Extra:关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Using
temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢

extra列返回的描述的意义

Distinct:一旦MYSQL找到了与行相联合匹配的行,就不再搜索了

Not exists: MYSQL优化了LEFT
JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了

Range checked for each Record(index
map:#):没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一

Using filesort: 看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行

Using index: 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候

Using temporary 看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER
BY上,而不是GROUP BY上

Where used 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题不同连接类型的解释(按照效率高低的顺序排序)

system 表只有一行:system表。这是const连接类型的特殊情况

const:表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待

eq_ref:在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用

ref:这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好

range:这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况

index: 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)

ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免

时间: 2024-10-15 19:05:23

mysql测试索引在表中的作用的相关文章

MySQL InnoDB 索引组织表 &amp; 主键作用

InnoDB 索引组织表 一.索引组织表定义 在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT). 在InnoDB存储引擎中,每张表都有个主键(Primary key),如果在创建表时没有地定义主键,则InnoDB存储引擎会选择表中符合条件的列去创建主键. 条件: 1.  首先判断表中是否有非空的唯一索引(Unique NOT NULL),如果有,则该列即为主键. 2. 如果不符合上述条件,InnoDB存储

MySQL学习笔记-操作数据表中的记录

MySQL学习笔记-操作数据表中的记录 1.插入记录 INSERT INSERT [INTO] tbl_name [(col_name,...)] {VAULES|VALUE} ({expr|DEFAULT},...),(...),... 例,插入单条记录: mysql> USE testDatabase changed mysql> CREATE TABLE users(    -> id SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,   

Mysql 如何删除数据表中的重复数据!

1.使用distinct查询所有不重复的记录 2.创建数据表相同结构的临时表,将第一步的数据复制进去 create temporary table if not exists student_temp as (select distinct(name), sex from student); 3.truncate table student; 4.insert into student(id,name,sex) select null,name,sex from student_temp; My

mysql统计一张表中条目个数的方法

统计一张表中条目的个通常的SQL语句是: select count(*) from tableName; #or select count(1) from tableName; #or 统计一个列项,如ID select count(ID) 另外,可通过使用information_schema统计个数 MySQL中有一个名为 information_schema 的数据库,在该库中有一个 TABLES 表,这个表主要字段分别是: TABLE_SCHEMA : 数据库名 TABLE_NAME:表名

mysql添加索引(建表之后)

一.使用ALTER TABLE语句创建索引 语法如下: 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) ; 其中包括普通索引.UNIQUE索引和PRIMARY KEY索引3种创建索引的格式,table_name是要增加索引

MySQL批量更新不同表中的数据

今天翻到以前写的批量更新表中的数据的存储过程,故在此做一下记录. 当时MySQL中的表名具有如下特征,即根据需求将业务表类型分为了公有.私有和临时三种类型,即不同的业务对应三张表,而所做的是区分出是什么类型(公有.私有.临时)的业务表对数据的固定字段做统一规律的处理. 下面为当时所编写的存储过程: BEGIN DECLARE done INT; DECLARE v_table_name VARCHAR(100); DECLARE v_disable VARCHAR(100); DECLARE v

修改MySQL数据库中表和表中字段的编码方式的方法

今天向MySQL数据库中的一张表添加含有中文的数据,可是老是出异常,检查程序并没有发现错误,无奈呀,后来重新检查这张表发现表的编码方式为latin1并且原想可以插入中文的字段的编码方式也是latin1,然后再次仔细观察控制台输出的异常,进一步确定是表和表中字段编码不当造成的,那就修改表和其中对应的字段呗,网上找了一会儿,你别说还真有,执行完sql脚本后果然可以存入中文了,尽管如此还是认为有必要总结一下,古人云:好记性不如烂笔头嘛,呵呵呵. 修改表的编码方式:ALTER TABLE `test`

mysql -- 存储过程 往数据表中新增字段

需求: 往某数据库的某个表中新增一个字段(若该字段已存在,则不做操作:若该字段不存在,则新增) 百度了n久,没有符合要求的例子,只有参考加自己琢磨,最终终于给弄出来了,以下是几个版本的更迭 第一版: DELIMITER $$ CREATE PROCEDURE insert_column() BEGIN IF NOT EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema='ltivalley' AND table_na

MYSQL自定义函数实现表中递归层次的展现

1.现在以菜单表为例,在数据库中创建表test_menu. 2.在表中创建一些实例数据 现在的菜单层次为cd_1与cd_2为一级菜单,cd_1下分为cd_1_1与cd_1_2两个二级菜单,cd_1_1下有个三级菜单cd_1_1_1,目录结构如下 cd_1 cd_1_1 cd_1_1_1 cd_1_2 cd_2 3.创建自定义函数 4.查询菜单层次 在此,菜单的各层次就很清晰的展现出来了.