iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL组合索引(多列索引)使用与优化案例详解
  • 448
分享到

MySQL组合索引(多列索引)使用与优化案例详解

mysql组合索引使用mysql索引 2022-07-04 11:07:11 448人浏览 泡泡鱼
摘要

目录1、多列索引2、测试案例及过程2.1 创建一个测试数据库和数据表2.2 添加两个单列索引2.3 查询一条数据利用到两个列的索引2.4 查看执行计划2.5 然后删除以上索引,添加多列索引2.6 再次查询3、多列索引的使

1、多列索引

我们经常听到一些人说"把WHERE条件里的列都加上索引",其实这个建议非常错误。

在多个列上建立单独的索引大部分情况下并不能提高Mysql的查询性能。mysql 在5.0之后引入了一种叫“索引合并”(index merge)的策略,一定程度上可以使用表上的多个单列索引来定位指定的行。但是当服务器对多个索引做联合操作时,通常需要耗费大量CPU和内存资源在算法缓存排序和合并操作上,特别是当其中有些索引的选择性不高,需要合并扫描大量的数据的时候。这个时候,我们需要一个多列索引。

2、测试案例及过程

2.1 创建一个测试数据库和数据表

 CREATE DATABASE IF NOT EXISTS db_test default charset utf8 COLLATE utf8_general_ci; 
use db_test;
CREATE TABLE payment (  
    id        INT UNSIGNED NOT NULL AUTO_INCREMENT,  
    staff_id  INT UNSIGNED NOT NULL,
    customer_id INT UNSIGNED NOT NULL, 
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

利用存储过程插入1000w 行随机数据(表引擎可以先设置为 MyISAM,然后改为 InnoDB)

DROP PROCEDURE IF EXISTS add_payment;  
DELIMITER //
    create PROCEDURE add_payment(in num INT)
    BEGIN
        DECLARE rowid INT DEFAULT 0;
        SET @exesql = 'INSERT INTO payment(staff_id, customer_id) values (?, ?)';
        WHILE rowid < num DO
            SET @staff_id = (1 + FLOOR(5000*RAND()) ); 
            SET @customer_id = (1 + FLOOR(500000*RAND()));
            SET rowid = rowid + 1;
            prepare stmt FROM @exesql;
            EXECUTE stmt USING @staff_id, @customer_id;            
        END WHILE;
    END //
DELIMITER ;

2.2 添加两个单列索引

(执行过程要花点时间,建议分开一句一句执行):

ALTER TABLE `payment` ADD INDEX idx_customer_id(`customer_id`);
ALTER TABLE `payment` ADD INDEX idx_staff_id(`staff_id`);

2.3 查询一条数据利用到两个列的索引

select count(*) from payment where staff_id = 2205 AND customer_id = 93112;

2.4 查看执行计划

mysql> explain select count(*)  from payment  where staff_id =  2205  AND customer_id =  93112;
+----+-------------+---------+-------------+------------------------------+------------------------------+---------+------+-------+-------------------------------------------------------------------------+
| id | select_type | table   | type        | possible_keys                | key                          | key_len | ref  | rows  | Extra                                                                   |
+----+-------------+---------+-------------+------------------------------+------------------------------+---------+------+-------+-------------------------------------------------------------------------+
|  1 | SIMPLE      | payment | index_merge | idx_customer_id,idx_staff_id | idx_staff_id,idx_customer_id | 4,4     | NULL | 11711 | Using intersect(idx_staff_id,idx_customer_id); Using where; Using index |
+----+-------------+---------+-------------+------------------------------+------------------------------+---------+------+-------+-------------------------------------------------------------------------+
1 row in set (0.00 sec)

可以看到 type 是 index_merge,Extra 中提示 Using intersect(idx_staff_id,idx_customer_id);这便是索引合并,利用两个索引,然后合并两个结果(取交集或者并集或者两者都有)

查询结果:

mysql> select count(*)  from payment  where staff_id =  2205  AND customer_id =  93112 ;
+----------+
| count(*) |
+----------+
|   178770 |
+----------+
1 row in set (0.12 sec)

2.5 然后删除以上索引,添加多列索引

ALTER TABLE payment DROP INDEX idx_customer_id;
ALTER TABLE payment DROP INDEX idx_staff_id;
ALTER TABLE `payment` ADD INDEX idx_customer_id_staff_id(`customer_id`, `staff_id`);

注意,多列索引很关注索引列的顺序(因为 customer_id 的选择性更大,所以把它放前面)。

2.6 再次查询

mysql> select count(*)  from payment  where staff_id =  2205  AND customer_id =  93112;
+----------+
| count(*) |
+----------+
|   178770 |
+----------+
1 row in set (0.05 sec)

发现多列索引加快的查询(这里数据量还是较小,更大的时候比较更明显)。

3、多列索引的使用顺序

3.1 怎么选择建立组合索引时,列的顺序

多列索引的列顺序至关重要,如何选择索引的列顺序有一个经验法则:将选择性最高的列放到索引最前列(但是不是绝对的)。经验法则考虑全局的基数和选择性,而不是某个具体的查询:

mysql> select count(DISTINCT staff_id) / count(*) AS staff_id_selectivity, count(DISTINCT customer_id) / count(*) AS customer_id_selectivity, count(*) from payment\G;
*************************** 1. row ***************************
   staff_id_selectivity: 0.0005
customer_id_selectivity: 0.0500
               count(*): 10000000
1 row in set (6.29 sec)

customer_id 的选择性更高,所以将它作为索引列的第一位。

3.2 组合索引的使用规则

索引可以理解成排好序的数据结构。组合索引可以这样理解,比如(a,b,c),abc 都是排好序的,在任意一段 a 的下面 b 都是排好序的,任何一段 b 下面  c都是排好序的;

MySQL组合索引(多列索引)使用与优化案例详解

生效的规则是:从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引部分起作用,断点后面的索引没有起作用; 

比如:

where a=3 and b=45 and c=5 .... 这种三个索引顺序使用中间没有断点,全部发挥作用;
where a=3 and c=5... 这种情况下b就是断点,a发挥了效果,c没有效果
where b=3 and c=4... 这种情况下a就是断点,在a后面的索引都没有发挥作用,这种写法联合索引没有发挥任何效果;
where b=45 and a=3 and c=5 .... 这个跟第一个一样,全部发挥作用,abc只要用上了就行,跟写的顺序无关

(a,b,c)多列索引使用的示例,说明:(a,b,c)组合索引和(a,c,b)是不一样的

(0)    select * from mytable where a=3 and b=5 and c=4;
abc三个索引都在where条件里面用到了,而且都发挥了作用
(1)    select * from mytable where  c=4 and b=6 and a=3;
这条语句列出来只想说明 mysql没有那么笨,where里面的条件顺序在查询之前会被mysql自动优化,效果跟上一句一样
(2)    select * from mytable where a=3 and c=7;
a用到索引,b没有用,所以c是没有用到索引效果的
(3)    select * from mytable where a=3 and b>7 and c=3;
a用到了,b也用到了,c没有用到,这个地方b是范围值,也算断点,只不过自身用到了索引
(4)    select * from mytable where b=3 and c=4;
因为a索引没有使用,所以这里 bc都没有用上索引效果
(5)    select * from mytable where a>4 and b=7 and c=9;
a用到了  b没有使用,c没有使用
(6)    select * from mytable where a=3 order by b;
a用到了索引,b在结果排序中也用到了索引的效果,前面说了,a下面任意一段的b是排好序的
(7)    select * from mytable where a=3 order by c;
a用到了索引,但是这个地方c没有发挥排序效果,因为中间断点了,使用 explain 可以看到 filesort
(8)    select * from mytable where b=3 order by a;
b没有用到索引,排序中a也没有发挥索引效果

到此这篇关于MySQL组合索引(多列索引)使用与优化的文章就介绍到这了,更多相关mysql组合索引使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL组合索引(多列索引)使用与优化案例详解

本文链接: https://www.lsjlt.com/news/33178.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SQL优化案例分享--联合索引
    下面这个SQL如何优化:desc select count(*) as total from Art_Person a, Art_Works b where a.PersonCode=b...
    99+
    2024-04-02
  • mysql 索引使用及优化详情
    目录前言mysql索引原理mysql索引分类索引创建语法1、创建索引2、查看索引3、删除索引4、为 username和password创建联合索引5、给user表添加一个info的字...
    99+
    2024-04-02
  • Mysql索引的使用-组合索引+跳跃条件
    关于MYSQL组合索引的使用,官方对下面的例子的说法是可以使用索引:KEY(key_part1,key_part2,key_part3)select .... from table wher...
    99+
    2024-04-02
  • MySQL中的组合索引与单列索引的区别有哪些
    本篇内容介绍了“MySQL中的组合索引与单列索引的区别有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • mysql多个联合索引的案例分析
    小编给大家分享一下mysql多个联合索引的案例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!MySQL中索引规则:1、需要加...
    99+
    2024-04-02
  • MySQL使用索引优化性能
    目录1.索引问题2.索引的存储分类3.如何使用索引3.1使用索引3.2存在索引但不使用索引4.查看索引使用情况5.两个简单实用的优化方法5.1定期分析表和检查表5.2定期优化表1.索...
    99+
    2024-04-02
  • MySQL组合索引与最左匹配原则详解
    前言 之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,最近面试时和面试官交流,发现遗漏了些东西,这里自己整理一下这方面的内容。 什么时候创建组合索引? 当我们...
    99+
    2024-04-02
  • MySQL中如何使用多列索引
    MySQL中如何使用多列索引,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。多列索引我们经常听到一些人说"把WHERE条件里的...
    99+
    2024-04-02
  • MySQL中索引与优化的示例分析
    这篇文章主要介绍MySQL中索引与优化的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!索引与优化1、选择索引的数据类型MySQL支持很多数据类型,选择合适的数据类型存储数据对...
    99+
    2024-04-02
  • Mysql索引选择以及优化详解
    目录索引模型 B+Tree 索引选择 索引优化 索引选择性 覆盖索引 最左前缀原则+索引下推前缀索引唯一索引索引失效总结索引模型 哈希表 适用于只有等值查询的场景,Memor...
    99+
    2024-04-02
  • mysql添加索引方法详解(Navicat可视化加索引与sql语句加索引)
    目录使用索引的场景:下面是通过sql语句添加索引的方法:1、普通索引1)、直接创建索引2)、修改表结构的方式添加索引3)、删除索引2、唯一索引1)、创建唯一索引2)、修改表结构3、主键索引4、组合索引5、全文索引1)、创...
    99+
    2024-04-02
  • MySQL数据库索引及优化的示例详解
    目录一、mysql 索引简介二、索引优化实战三、总结在日常的数据库使用过程中,我们经常需要对数据进行查询、插入、删除等操作。为了提高这些操作的效率,数据库的性能优化显得尤为重要。本文将带你深入了解 MySQL 数据库的索...
    99+
    2023-05-19
    MySQL索引优化方式 MySQL索引 MySQL优化
  • MySQL中的索引优化技巧详解
    MySQL是一个开源的关系型数据库管理系统,被广泛应用于各种网站和应用程序中。索引是MySQL中关键的性能优化手段之一,对于大型数据表来说尤为重要。本文将介绍MySQL中的索引优化技巧,并附加相应的代码示例。一、什么是索引索引是一种特殊的数...
    99+
    2023-10-22
    技巧 优化 索引
  • MySQL中怎么使用索引优化
    本篇内容主要讲解“MySQL中怎么使用索引优化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL中怎么使用索引优化”吧!使用索引优化索引是数据库优化最常用也是最重要的手段之一,通过索引通常...
    99+
    2023-07-05
  • MySQL中or、in、union与索引优化详析
    本文缘起自《一分钟了解索引技巧》的作业题。 假设订单业务表结构为: order(oid, date, uid, status, money, time, …) ...
    99+
    2024-04-02
  • MySQL索引失效十种场景与优化方案
    目录1 数据准备1.1 新建数据表1.2 新增100万条数据2 基础知识2.1 explain type2.2 explain Extra3 索引失效场景3.1 查询类型错误3.1....
    99+
    2023-05-19
    MySQL索引失效场景 MySQL索引优化 MySQL索引失效与优化
  • MySQL索引与事务定义到使用详解
    目录1.索引的本质2.索引的使用2.1查看索引2.2创建索引2.3删除索引3.索引的数据结构3.1B树3.2B+树4.事务4.1事物的回滚(rollback)4.2事务的四大特性(ACID)4.2.1 原子性4.2.2 ...
    99+
    2022-12-03
    MySQL索引与事务 MySQL事务 MySQL索引
  • 当Mysql行锁遇到复合主键与多列索引的示例分析
    这篇文章给大家分享的是有关当Mysql行锁遇到复合主键与多列索引的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。背景在配合其他项目组做系统压测,过程中出现了偶发的死锁问题...
    99+
    2024-04-02
  • MySQL的索引原理以及查询优化详解
    目录一、介绍1.什么是索引?2.为什么要有索引呢?二、索引的原理一 索引原理二 磁盘IO与预读三、索引的数据结构四、Mysql索引管理一、功能二、MySQL的索引分类三、 索引的两大...
    99+
    2024-04-02
  • 如何通过索引优化PHP与MySQL的多表查询?
    在开发Web应用程序时,经常会涉及到与数据库进行交互的操作,尤其是对于关系型数据库来说,多表查询是非常常见的操作。然而,当数据量过大,查询复杂度增加时,多表查询的性能可能会受到一定的影响。为了提高查询效率,我们可以通过优化索引来进行调整。索...
    99+
    2023-10-21
    MySQL PHP 索引优化 多表查询
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作