- 浏览: 27571 次
- 性别:
- 来自: 杭州
最新评论
-
qdujunjie:
楼主我有个问题,静态资源设置cache-control是可以进 ...
web cache 机制 (cache-control)
陆陆续续看了一些关于mysql innodb 引擎的文档,但是还是不能回答我自己如何根据查询语言建立索引的问题,所以必须做一些小实验才能解开上述疑惑。
首先,总结下一些文档的内容:
- innodb用的是b+ tree,PK索引树的叶节点是数据文件也就是record,而辅助索引(也就是非PK字段的索引的叶节点则是指向PK索引树的指针),从而达到加快查询的目的。
- 索引并非一张表必然建立的,如果数据量较小的话,建议还是不采取建立索引,等查询速度变慢,再建立索引。
本文章的主要目的在于:
mysql innodb如何使用索引,即一条sql语句如何使用索引。
测试环境
- OS:Linux debian 2.6.32-5-amd64 #1 SMP Wed May 18 23:13:22 UTC 2011 x86_64 GNU/Linux 虚拟机
- mysqladmin Ver 8.42 Distrib 5.1.49, for debian-linux-gnu on x86_64
建立基础表结构
建立基础表
create table test ( col_pk int primary key,col_index_1 int,col_index_compound_1 int,col_index_coumpount_2 int)engine=innodb,character set=gbk;
查看主键索引
show indexes from test;
写道
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| test | 0 | PRIMARY | 1 | col_pk | A | 0 | NULL | NULL | | BTREE | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| test | 0 | PRIMARY | 1 | col_pk | A | 0 | NULL | NULL | | BTREE | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
我们如下查询:
explain select * from test where col_pk = 1; +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables | +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
从上面可以看出innoDB选择的常量表进行查询,因为表中没有数据所以查询为不可能执行
然后我们插入数据:
insert into test values(1,1,1,1); insert into test values(2,1,1,1); --再次查询 explain select * from test where col_pk = 1; +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | test | const | PRIMARY | PRIMARY | 4 | const | 1 | | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ 1 row in set (0.00 sec)
插入数据后我们可以看出,这个查询会使用索引col_pk
接着我们在test建立索引col_index_1和(col_index_compound_1和col_index_compound_2)的索引
create index index_col_index_1 on test(col_index_1); create index index_col_index_compound_12 on test(col_index_compound_1,col_index_coumpount_2); mysql> show indexes from test; +-------+------------+-----------------------------+--------------+-----------------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +-------+------------+-----------------------------+--------------+-----------------------+-----------+-------------+----------+--------+------+------------+---------+ | test | 0 | PRIMARY | 1 | col_pk | A | 2 | NULL | NULL | | BTREE | | | test | 1 | index_col_index_1 | 1 | col_index_1 | A | 2 | NULL | NULL | YES | BTREE | | | test | 1 | index_col_index_compound_12 | 1 | col_index_compound_1 | A | 2 | NULL | NULL | YES | BTREE | | | test | 1 | index_col_index_compound_12 | 2 | col_index_coumpount_2 | A | 2 | NULL | NULL | YES | BTREE | | +-------+------------+-----------------------------+--------------+-----------------------+-----------+-------------+----------+--------+------+------------+---------+ 4 rows in set (0.00 sec)
可以从上面看出,我们已经拥有了3个索引,然后进行我们的查询
mysql> explain select * from test where col_pk = 1; +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | test | const | PRIMARY | PRIMARY | 4 | const | 1 | | +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+ 1 row in set (0.00 sec) mysql> explain select * from test where col_pk = 1 and col_index_1=1; +----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | test | const | PRIMARY,index_col_index_1 | PRIMARY | 4 | const | 1 | | +----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------+ 1 row in set (0.00 sec)
从上面两个对比中发现只有有pk作为select的对象则,一定会使用pk索引
mysql> explain select * from test where col_index_1=1 order by col_pk; +----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+ | 1 | SIMPLE | test | ref | index_col_index_1 | index_col_index_1 | 5 | const | 1 | Using where | +----+-------------+-------+------+-------------------+-------------------+---------+-------+------+-------------+ 1 row in set (0.00 sec) mysql> explain select * from test order by col_pk; +----+-------------+-------+-------+---------------+---------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+---------+---------+------+------+-------+ | 1 | SIMPLE | test | index | NULL | PRIMARY | 4 | NULL | 2 | | +----+-------------+-------+-------+---------------+---------+---------+------+------+-------+ 1 row in set (0.00 sec)
上述例子则说明where 的过滤条件会优于ordery by
mysql> explain select * from test where col_pk = 1 or col_index_1=1; +----+-------------+-------+------+---------------------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------------------+------+---------+------+------+-------------+ | 1 | SIMPLE | test | ALL | PRIMARY,index_col_index_1 | NULL | NULL | NULL | 2 | Using where | +----+-------------+-------+------+---------------------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec) mysql> explain select * from test where col_index_1=1 or col_pk =1; +----+-------------+-------+------+---------------------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------------------+------+---------+------+------+-------------+ | 1 | SIMPLE | test | ALL | PRIMARY,index_col_index_1 | NULL | NULL | NULL | 2 | Using where | +----+-------------+-------+------+---------------------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec)
上述例子说明两个问题:
- where条件的前后顺序不影响索引的选择
- or关键字会导致扫描所有记录
mysql> explain select * from test where col_index_compound_1=1 and col_pk =1; +----+-------------+-------+-------+-------------------------------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+-------------------------------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | test | const | PRIMARY,index_col_index_compound_12 | PRIMARY | 4 | const | 1 | | +----+-------------+-------+-------+-------------------------------------+---------+---------+-------+------+-------+ 1 row in set (0.00 sec) mysql> explain select * from test where col_index_1=1 and col_pk =1; +----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | test | const | PRIMARY,index_col_index_1 | PRIMARY | 4 | const | 1 | | +----+-------------+-------+-------+---------------------------+---------+---------+-------+------+-------+ 1 row in set (0.00 sec)
以上例子说明,and的情况下,主键优先
mysql> explain select * from test where col_index_compound_1=2 and col_index_1 =1; +----+-------------+-------+------+-----------------------------------------------+-------------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+-----------------------------------------------+-------------------+---------+-------+------+-------------+ | 1 | SIMPLE | test | ref | index_col_index_1,index_col_index_compound_12 | index_col_index_1 | 5 | const | 1 | Using where | +----+-------------+-------+------+-----------------------------------------------+-------------------+---------+-------+------+-------------+ 1 row in set (0.00 sec) mysql> explain select * from test where col_index_compound_1=2 and col_index_1 =1 and col_index_coumpount_2=1; +----+-------------+-------+------+-----------------------------------------------+-------------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+-----------------------------------------------+-------------------+---------+-------+------+-------------+ | 1 | SIMPLE | test | ref | index_col_index_1,index_col_index_compound_12 | index_col_index_1 | 5 | const | 1 | Using where | +----+-------------+-------+------+-----------------------------------------------+-------------------+---------+-------+------+-------------+ 1 row in set (0.00 sec)上述例子说明,当联合索引和单索引没有交集的时候,单个索引会优先考虑
建立新索引 index_col_index_1_and_compound_1 create index index_col_index_1_and_compound_1 on test(col_index_1,col_index_compound_1);
mysql> explain select * from test where col_index_1=1 and col_index_compound_1=1; +----+-------------+-------+------+--------------------------------------------------------------------------------+-------------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+--------------------------------------------------------------------------------+-------------------+---------+-------+------+-------------+ | 1 | SIMPLE | test | ref | index_col_index_1,index_col_index_compound_12,index_col_index_1_and_compound_1 | index_col_index_1 | 5 | const | 1 | Using where | +----+-------------+-------+------+--------------------------------------------------------------------------------+-------------------+---------+-------+------+-------------+ 1 row in set (0.00 sec) mysql> explain select * from test where col_index_compound_1=2 and col_index_1 =1; +----+-------------+-------+------+--------------------------------------------------------------------------------+-------------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+--------------------------------------------------------------------------------+-------------------+---------+-------+------+-------------+ | 1 | SIMPLE | test | ref | index_col_index_1,index_col_index_compound_12,index_col_index_1_and_compound_1 | index_col_index_1 | 5 | const | 1 | Using where | +----+-------------+-------+------+--------------------------------------------------------------------------------+-------------------+---------+-------+------+-------------+ 1 row in set (0.00 sec)
从上述看出,单索引还是会优先选择的
总结:
- 主键是最优选择
- 单索引会优先选择
相关推荐
在深入探讨MySQL Innodb索引之前,我们先了解几种基本的树形数据结构,包括二叉搜索树、B树、B+树以及B*树。 ##### 1.1 搜索二叉树(Binary Search Tree) 搜索二叉树是一种特殊的二叉树,每个节点至多有两个子...
在MySQL数据库系统中,InnoDB存储引擎是默认的...总之,理解和优化InnoDB索引大小是提高MySQL数据库性能的关键步骤之一。通过合理设计索引,不仅可以节省存储空间,还能显著提升查询效率,从而优化整体系统的运行效能。
### 辛星笔记之InnoDB索引 #### 第一节:算法基础 ##### 二分查找法 二分查找法(Binary Search),又称折半查找法,是一种高效的查找算法,适用于有序数组。它的工作原理是首先将目标值与数组中间位置的元素进行...
MySQL数据库的InnoDB存储引擎广泛使用BTree索引来优化查询性能。BTree索引是一种常见的索引类型,尤其适用于范围查询和排序操作。在MySQL中,InnoDB存储引擎的索引分为聚簇索引(主键索引)和非聚簇索引(二级索引)...
MySQL数据库中,InnoDB存储引擎的索引与存储结构是数据库性能优化的关键,了解这些机制对于数据库管理员和开发人员至关重要。InnoDB是MySQL中支持事务处理的存储引擎,它具有ACID(原子性、一致性、隔离性、持久性)...
### MySQL体系结构及原理(innodb)图文完美解析 #### 宏观认识 在深入探讨MySQL的体系结构及其核心组件InnoDB之前,我们先来理解几个基础概念。 1. **MySQL简介** MySQL是一种开源的关系型数据库管理系统(RDBMS)...
### MySQL InnoDB 查询优化实现分析 #### 一、目的与背景 本文旨在深入探讨 MySQL + InnoDB 存储引擎在实现查询优化时所采取的方法及其内部机制。通过具体实例和详细的技术解析,揭示 InnoDB 如何高效处理各种查询...
最近在学习MySQL技术内幕 InnoDB存储引擎 第2版,整理了一些文档分享出来,同时也方便以后查看。若有不当之处,烦请批评指正。 1. MySQL体系结构和存储引擎 2. InnoDB存储引擎 2.1 InnoDB体系结构 2.2 ...
Mysql 的InnoDB引擎的相关笔记 1.0.MySQL架构到innoDB架构.md 1.1.0.InnoDB——简介.md 1.1.1.InnoDB——关键特性.md 1.2.0.InnoDB内存结构——缓冲池.md 1.2.1.InnoDB内存结构——log buffer.md 1.2.2.InnoDB内存...
深入学习《MySQL内核:InnoDB存储引擎 卷1》,读者可以了解到InnoDB的内部工作机制,如如何处理B+树索引、事务的提交与回滚、锁的实现以及内存管理等内容,这对于优化数据库性能、解决并发问题、设计高效的数据模型...
### MySQL Innodb 引擎特性详解 #### 一、MySQL Innodb 引擎概述 MySQL是一种广泛使用的开源关系型数据库管理系统(RDBMS),它...同时,通过对InnoDB的相关参数进行合理调整,可以在很大程度上提高系统的整体性能。
### MySQL与InnoDB性能分析 #### MySQL架构概览 MySQL是一种关系型数据库管理系统,由瑞典MySQL AB公司开发,目前由Oracle公司维护。MySQL的核心组成部分包括服务器端、存储引擎以及一系列支持服务。 - **服务器...
《MySQL内核:InnoDB存储引擎 卷1》由资深MySQL专家,机工畅销图书作者亲自执笔,在以往出版的两本InnoDB介绍性图书的基础之上,更深入地介绍InnoDB存储引擎的内核,例如latch、B+树索引、事务、锁等,从源代码的...
MySQL索引 聚集索引 如果你想了解MySQL索引查询优化,你首先应该对MySQL数据组织结构、B-Tree索引、聚集索引,次要索引有一定的了解,才能够更好地理解MySQL查询优化行为。这里主要探讨MySQL InnoDB的聚集索引。
MySQL InnoDB 存储引擎的二级索引是其特性之一,用于提高数据查询效率。在InnoDB表中,除了主键索引(Primary Key),还可以创建一个或多个辅助索引(Secondary Indexes)。这些索引的叶子节点并不直接存储行数据,...