如何给mysql创建组合索引并分析索引命中(官方校正版)

MySQL 可以使用多列索引来执行测试索引中所有列的查询,或者仅测试第一列、前两列、前三列等的查询。如果您在索引定义中以正确的顺序指定列,则单个复合索引可以加速同一表上的几种查询。

MySQL 可以创建复合索引(即在多个列上建立索引)。索引最多可包含 16 个列。

对于某些数据类型,您可以索引列的前缀。

多列索引可以被视为一个排序数组,其行包含通过连接索引列的值而创建的值。

以下语句可以通过命令行操作,如需要SQL工具可以试用SQLynx或MySQL workbench等

作为复合索引的替代方法,您可以引入一个基于其他列的信息进行"散列"的列。如果此列很短、相当唯一且已编入索引,则它可能比在许多列上建立"宽"索引更快。在 MySQL 中,使用此额外列非常容易:

language-sql 复制代码
SELECT * FROM tbl_name
  WHERE hash_col=MD5(CONCAT(val1,val2))
  AND col1=val1 AND col2=val2;

假设有一张表具有以下规格:

language-sql 复制代码
CREATE TABLE test (
    id         INT NOT NULL,
    last_name  CHAR(30) NOT NULL,
    first_name CHAR(30) NOT NULL,
    PRIMARY KEY (id),
    INDEX name (last_name,first_name)
);

索引是和列name的索引 。索引可用于在指定已知范围内的值的查询中查找 和 值的组合。它还可以用于仅指定值的查询, 因为该列是索引的最左前缀(如本节后面所述)。因此,索引用于以下查询中的查找: last_name``first_name``last_name``first_name``last_name``name

language-sql 复制代码
SELECT * FROM test WHERE last_name='Jones';

SELECT * FROM test
  WHERE last_name='Jones' AND first_name='John';

SELECT * FROM test
  WHERE last_name='Jones'
  AND (first_name='John' OR first_name='Jon');

SELECT * FROM test
  WHERE last_name='Jones'
  AND first_name >='M' AND first_name < 'N';

但是,name索引 用于以下查询中的查找:

language-sql 复制代码
SELECT * FROM test WHERE first_name='John';

SELECT * FROM test
  WHERE last_name='Jones' OR first_name='John';

假设您发出以下 SELECT语句:

language-sql 复制代码
SELECT * FROM tbl_name
  WHERE col1=val1 AND col2=val2;

col1如果和 上存在多列索引col2,则可直接提取相应的行。如果 和 上存在单独的单列索引 col1,则col2优化器将尝试使用索引合并优化(请参见 第 10.2.1.3 节"索引合并优化"),或者尝试通过确定哪个索引排除更多行并使用该索引提取行来找到最严格的索引。

如果表具有多列索引,则优化器可以使用索引的任何最左前缀来查找行。例如,如果您在 上有一个三列索引,则您具有对、和 的 (col1, col2, col3)索引搜索功能 。 (col1)(col1, col2)(col1, col2, col3)

如果列不构成索引的最左前缀,则 MySQL 无法使用索引执行查找。假设您有SELECT如下所示的语句:

sql 复制代码
SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;

如果 上有索引(col1, col2, col3),则只有前两个查询会使用索引。第三和第四个查询确实涉及索引列,但不使用索引来执行查找,因为(col2)(col2, col3)不是的最左前缀 (col1, col2, col3)

相关推荐
iVictor1 小时前
分享一个 MySQL binlog 分析小工具
mysql
老华带你飞1 小时前
口腔助手|口腔挂号预约小程序|基于微信小程序的口腔门诊预约系统的设计与实现(源码+数据库+文档)
java·数据库·微信小程序·小程序·论文·毕设·口腔小程序
hqxstudying1 小时前
J2EE模式---服务层模式
java·数据库·后端·spring·oracle·java-ee
Yu_Lijing1 小时前
MySQL进阶学习与初阶复习第四天
数据库·学习·mysql
大熊程序猿1 小时前
net8.0一键创建支持(Orm-Sqlite-MySql-SqlServer)
数据库·mysql·sqlite
-SGlow-10 小时前
MySQL相关概念和易错知识点(2)(表结构的操作、数据类型、约束)
linux·运维·服务器·数据库·mysql
明月56611 小时前
Oracle 误删数据恢复
数据库·oracle
水瓶_bxt12 小时前
Centos安装HAProxy搭建Mysql高可用集群负载均衡
mysql·centos·负载均衡
♡喜欢做梦12 小时前
【MySQL】深入浅出事务:保证数据一致性的核心武器
数据库·mysql
遇见你的雩风12 小时前
MySQL的认识与基本操作
数据库·mysql