MySQL两表索引优化

建表语句

CREATE TABLE IF NOT EXISTS `class`(
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`card` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY(`id`)
);

CREATE TABLE IF NOT EXISTS `book`(
`bookid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`card` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY(`bookid`)
);

INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));

使用explain对sql进行检查

mysql> explain SELECT * FROM class LEFT JOIN book ON class.card = book.card;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                              |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
|  1 | SIMPLE      | class | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | NULL                                               |
|  1 | SIMPLE      | book  | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)
  • 可以看到type都为all(执行全表查询)
  • 使用了join缓冲区(其使用的算法为Block Nested-Loop(BNL))

添加索引

  • 对book表的card属性添加索引
alter table `book` add index Y(`card`);
  • 再次用explain查看之前的sql

    mysql> explain SELECT * FROM class LEFT JOIN book ON class.card = book.card;
    +----+-------------+-------+------------+------+---------------+------+---------+-----------------+------+----------+-------------+
    | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref             | rows | filtered | Extra       |
    +----+-------------+-------+------------+------+---------------+------+---------+-----------------+------+----------+-------------+
    |  1 | SIMPLE      | class | NULL       | ALL  | NULL          | NULL | NULL    | NULL            |   24 |   100.00 | NULL        |
    |  1 | SIMPLE      | book  | NULL       | ref  | Y             | Y    | 4       | test.class.card |    1 |   100.00 | Using index |
    +----+-------------+-------+------------+------+---------------+------+---------+-----------------+------+----------+-------------+
    2 rows in set, 1 warning (0.00 sec)
    • 可以看到book表的type优化为了type, 且extra变为了using index, 不会再使用缓冲区了。
  • 对class表的card属性添加索引
    alter table `class` add index Y(`card`);
  • 再次用explain查看之前的sql
    mysql> explain SELECT * FROM class LEFT JOIN book ON class.card = book.card;
    +----+-------------+-------+------------+-------+---------------+------+---------+-----------------+------+----------+-------------+
    | id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref             | rows | filtered | Extra       |
    +----+-------------+-------+------------+-------+---------------+------+---------+-----------------+------+----------+-------------+
    |  1 | SIMPLE      | class | NULL       | index | NULL          | Y    | 4       | NULL            |   24 |   100.00 | Using index |
    |  1 | SIMPLE      | book  | NULL       | ref   | Y             | Y    | 4       | test.class.card |    1 |   100.00 | Using index |
    +----+-------------+-------+------------+-------+---------------+------+---------+-----------------+------+----------+-------------+
    2 rows in set, 1 warning (0.00 sec)
    
    • 可以看到type变为了index, ref 而 extra 都变为了Using index

可以得出的结论

  • 左连接时, 对右表建索引进行优化更重要(左表都保留, 必然全表扫描)
  • 右连接时, 对左表建索引进行优化更重要(右表都保留, 必然全表扫描)

原文地址:https://www.cnblogs.com/ronnieyuan/p/12160863.html

时间: 2024-10-12 13:19:14

MySQL两表索引优化的相关文章

MySQL两千万数据优化&迁移

最近有一张2000W条记录的数据表需要优化和迁移.2000W数据对于MySQL来说很尴尬,因为合理的创建索引速度还是挺快的,再怎么优化速度也得不到多大提升.不过这些数据有大量的冗余字段和错误信息,极不方便做统计和分析.所以我需要创建一张新表,把旧表中的数据一条一条取出来优化后放回新表: 一. 清除冗余数据,优化字段结构 2000W数据中,能作为查询条件的字段我们是预知的.所以将这部分数据单独创建新的字段,对于有规则的数据合理改变字段结构,比如身份证就是varchar(18).对于不重要的数据我们

mysql 多列索引优化

Mysql所有的列都可以使用索引,.对相关列使用索引是提高SELECT操作性能的最佳途径.根据存储引擎定义每个表的最大索引数和最大索引长度.所有存储引擎支持每个表至少16个索引,总索引长度至少256字节.在索引中使用col_name(length)语法,可以创建一个只使用char和archar列的第一个length个字符的索引,按这种方式只索引列的前缀可以索引文件小的多.MyISAm和INNODb存储引擎还支持对blob和text列的索引,但是必须指定索引长度.fulltext索引用于全文搜索不

MySQL如何利用索引优化ORDER BY排序语句

MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度. MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作. 通过索引优化来实现MySQL的ORDER BY语句优化: 1.ORDER BY的索引优化.如果一个SQL语句形如:SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort];在[sort]这个栏位上建立索引就可以实现利用索引进行order by

MySQL查看表索引

mysql> show index from tblname; mysql> show keys from tblname; · Table 表的名称. · Non_unique 如果索引不能包括重复词,则为0.如果可以,则为1. · Key_name 索引的名称. · Seq_in_index 索引中的列序列号,从1开始. · Column_name 列名称. · Collation 列以什么方式存储在索引中.在MySQL中,有值‘A’(升序)或NULL(无分类). · Cardinalit

mysql 两表联查分页排序效率优化

数据库中有两张表 t1 存储消息信息 +-----------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI |

Mysql学习总结(17)——MySQL数据库表设计优化

1.选择优化的数据类型 MySQL支持很多种不同的数据类型,并且选择正确的数据类型对于获得高性能至关重要.不管选择何种类型,下面的简单原则都会有助于做出更好的选择: (1).更小通常更好 一般来说,要试着使用正确地存储和表示数据的最小类型.更小的数据类型通常更快,因为它们使用了更少的磁盘空间.内存和CPU缓存,而且需要的CPU周期也更少. 但是要确保不人低估需要保存的值,在架构中的多个地方增加数据类型的范围是一件极其费力的工作.如果不确实需要什么数据类型,就选择你认为不会超出范围的最小类型. (

mysql数据库添加索引优化查询效率

项目中如果表中的数据过多的话,会影响查询的效率,那么我们需要想办法优化查询,通常添加索引就是我们的选择之一: 1.添加PRIMARY KEY(主键索引) mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2.添加UNIQUE(唯一索引) mysql>ALTER TABLE `table_name` ADD UNIQUE ( `column` ) 3.添加INDEX(普通索引) mysql>ALTER TABLE `ta

Mysql在建立索引优化时需要注意的问题

设计好mysql的索引可以让你的数据库飞起来,大大的提高数据库效率,设计mysql索引的时候有以下几点注意: 1.创建索引 对于查询占主要的应用来说,索引显得尤为重要.很多时候性能问题很简单的就是因为我们发忘了添加索引而造成的,或者说没有添加更为有效的索引导致.如果不加索引的话,那么查询任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下降.但是也不是什么情况下非要加索引不可,比如性别可能就只有两个值,建索引不仅没有优势,还

两表合并优化

需求: 需要将两个字段有部分相同其他不同,且行数都不相同的datatable根据keycolumn合并为一个table. 相当于做了一个left Join. 方法一: 自己写的最原始的方法 优点:在表合并方面能完美达到效果. 缺点:表很大时(几万行开始)速度相当慢,且容易内存溢出. 1 public static DataTable MergeTable(DataTable dtReturn, DataTable dtMerge, string keyName) 2 { 3 foreach (D