索引策略-多列索引

一. 前言

当我们对多列索引的理解不够深刻的时候,往往会为每个列创建独立的索引或者按照错误的顺序创建多列索引。

二. 案例说明

问题一: 为每个列创建独立索引

CREATE TABLE t(
    c1 INT,
    c2 INT,
    c3 INT,
    KEY(c1),
    KEY(c2),
    KEY(c3)
);

这种索引策略,一般都是由于人们听到一些专家诸如"把Where条件里面的列都建上索引"这样模糊的建议导致的。这样一来最好也只能是"一星"索引,其性能比真正最优的索引可能差几个数量级。有时如果无法设计一个"三星"索引,那么不如忽略掉Where子句,集中精力优化索引顺序,或者创建一个全覆盖索引

2.1 三星索引

一星: 索引将相关的记录放在一起
二星: 如果索引中的数据顺序查找顺序一致
三星: 如果索引中的列包含了查询中需要的全部列
在这里插入图片描述

三星索引的相关实践可以参考: 三星索引实战

2.2 Mysql底层对单列索引的处理

在多个列上建立独立的单列索引大部分情况下并不能提高Mysql的查询性能。Mysql 5.0 和更新版本引入了一种叫"索引合并"(index merge)的策略,一定程度上可以使用表上的多个单列索引来定位指定的行。更早版本的 Mysql只能使用其中某一个单列索引,然而这种情况下没有哪一个独立的单独索引是非常有效的。例如,下表 film_actor在字段 film_id 和 actor_id 各有一个单列索引。但对于下面这个查询的 Where 条件,这两个单列索引都不是好的选择:

建表语句:

CREATE TABLE `film_actor` (
  `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `actor_id` int(20) NOT NULL COMMENT '演员id',
  `film_id` int(20) DEFAULT NULL COMMENT '电影id',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_film_id` (`film_id`) USING BTREE,
  KEY `idx_actor_id` (`actor_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4

查询语句:

SELECT film_id, actor_id FROM film_actor
WHERE actor_id = 1 OR film_id = 1;

执行计划:
在这里插入图片描述

在老的 Mysql版本中,Mysql对这个查询会使用全表扫描。除非改下成如下的两个查询UNION的方式:

SELECT film_id, actor_id FROM film_actor WHERE actor_id = 1
UNION ALL
SELECT film_id, actor_id FROM film_actor WHERE film_id = 1
AND actor_id <> 1

执行计划:
在这里插入图片描述

但在Mysql 5.0和更新的版本中,查询能够同时使用两个单列索引进行扫描,并将结果进行合并。这种算法有三个变种: OR条件的联合(union),AND条件的相交(intersection),组合前两种情况的联合及相交。

Tips: 索引合并通过能在执行计划的 Extra上看到

在这里插入图片描述

2.3 索引合并背后的问题

索引合并策略有时候是一种优化的结果,但实际上更多的时候说明表的索引建的很糟糕。

  • 当出现服务器对多个索引做相交操作时(通常有多个AND条件),通常意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引。
  • 当服务器需要对多个索引做联合操作时(通常有多个OR条件),通常需要消耗大量CPU内存资源在算法的缓存,排序和合并操作上。特别是当中有些索引选择性不高,需要合并扫描返回大量数据的时候。
  • 更重要的是,优化器不会把这些计算到"查询成本"(cost) 中,优化器只关心随机页面读取。这会使得查询的成本被"低估",导致该执行计划还不如直接走全表扫描。这样做不但会消耗更多的CPU和内存资源,还可能会影响查询的并发性,但如果是单独运行这样的查询则往往会忽略对并发性的影响。通常来说,还不如像在Mysql 4.1 或者更早的时代一样,将查询改写成 UNION的方式往往更好。

如果在EXPLAIN中看到索引合并,应该好好检查一下查询和表的结构,看是不是已经是最优的。也可以通过参数 optimizer_switch 来关闭索引合并功能,也可以使用 Ignore index 提示让优化器忽略掉某些索引

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/314322.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python进阶必备】一文掌握re库:实战正则表达式

目录 re库初识 re库基础使用方法 compile()函数 基本用法 正则表达式常用规则字符 match与search方法 match search match/search findall与finditer方法 使用findall()返回所有匹配项 使用findall()提取多个组的匹配 使用finditer()逐个返回Match对象 使用findi…

Android14之解决Pixel手机联网出现感叹号(一百八十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

MySQL的Windows系统安装

一、MySQL的Windows系统安装 1、下载MySQL安装包 打开如下链接地址&#xff0c;下载安装包 2、安装并配置 双击下载好的安装包进行安装&#xff0c;出现如下界面&#xff1a; 选择【 Full 】选项&#xff0c;然后单击【 Next 】按钮。 出现如下界面&#xff0c;单击【 Execute…

数据结构实战:利用JavaScript和Python实现链表

文章目录 一、实战概述二、链表&#xff08;一&#xff09;链表概述&#xff08;二&#xff09;结点结构&#xff08;二&#xff09;链表结构 三、利用JavaScript实现链表&#xff08;一&#xff09;创建LinkedList.js&#xff08;二&#xff09;创建LinkedList.html&#xff0…

数字图像处理常用算法的原理和代码实现详解

本专栏详细地分析了常用图像处理算法的数学原理、实现步骤。配有matlab或C实现代码&#xff0c;并对代码进行了详细的注释。最后&#xff0c;对算法的效果进行了测试。相信通过这个专栏&#xff0c;你可以对这些算法的原理及实现有深入的理解&#xff01;   如有疑问&#xf…

中通快递批量查询方法

你是否经常需要处理大量的中通快递单号&#xff0c;却苦于一个个等待查询&#xff1f;现在&#xff0c;有了固乔快递查询助手&#xff0c;这个问题迎刃而解&#xff01;通过批量查询功能&#xff0c;你可以轻松管理、追踪你的中通快递单号&#xff0c;大大提高工作效率。 一、下…

结构体成员 分数比较大小

题目&#xff1a; 代码&#xff1a; #include <bits/stdc.h> #include<cstring>using namespace std;struct Num{double fenzi;double fenmu;char fenhao;};bool cmp(Num r1,Num r2){return r1.fenzi/r1.fenmu<r2.fenzi/r2.fenmu;}int main(){int n;Num num[n…

基于net6的asp.net core webapi项目打包为docker镜像,并推送至私有镜像仓库harbor中

基于net6的asp.net core webapi项目打包为docker镜像&#xff0c;并推送至私有镜像仓库harbor中 0、环境说明1、打包步骤1.1 创建Asp.net core WebApi项目1.2 在Asp.net core WebApi项目根目录下创建Dockerfile文件1.3 在子系统Ubuntu20.04.4中通过docker build生成docker镜像1…

游戏测试大揭秘,帮你轻松过关

游戏测试可以看作是软件测试的一个分支&#xff0c;黑盒测试最基本的要求是会玩游戏。小公司会要求测试能力更加全面的员工&#xff0c;其中除了功能测试还要会性能测试&#xff0c;兼容测试&#xff0c;弱网测试&#xff0c;自动化测试等。 游戏测试是游戏开发过程中必不可少…

vue2-手写轮播图

轮播图5长展示&#xff0c;点击指示器向右移动一个图片&#xff0c;每隔2秒移动一张照片&#xff01; <template><div class"top-app"><div class"carousel-container"><div class"carousel" ref"carousel">&…

Tensorflow2.0笔记 - 修改形状和维度

本次笔记主要使用reshape&#xff0c;transpose&#xff0c;expand_dim&#xff0c;和squeeze对tensor的形状和维度进行操作。 import tensorflow as tf import numpy as nptf.__version__#tensor的shape和维数获取 #假设下面这个tensor表示4张28*28*3的图片 tensor tf.rando…

RAG 详解

原文&#xff1a;GitHub - Tongji-KGLLM/RAG-Survey 目录 RAG调查 什么是RAG&#xff1f;RAG的范式 幼稚的 RAG高级 RAG模块化 RAG如何进行增强&#xff1f;RAG 还是微调&#xff1f;如何评估 RAG&#xff1f;前景 严峻的挑战多式联运扩展RAG的生态系统RAG论文清单 增强阶段 …

C++多线程学习[二]:线程的传参以及传参的一些坑

一、线程的传参 #include<iostream> #include<thread> #include<string> using namespace std; void threadtest(int a,double b,string str) {this_thread::sleep_for(100ms);cout << a << " " << b << " " &…

【Linux】编写第一个小程序:进度条

文章目录 1. 预备知识1.1 简单认识几个函数1.1.1 sleep()1.1.2 fflush()1.1.3 usleep()1.1.4 memset() 1.2 缓冲区1.3 回车与换行 2. 编写入门版的进度条2.1 基本逻辑2.2 美化效果2.3 代码实现2.4 执行效果 3. 编写升级版的进度条3.1 代码实现3.2 执行效果 1. 预备知识 1.1 简…

C++每日一练(15):简单幂计算

题目描述 输入两个数a和b&#xff0c;求a的b次方。 输入 输入两个整数a&#xff0c;b&#xff08;1<a<10&#xff0c;1<b<15&#xff09;。 输出 输出一个正整数&#xff0c;该值<1000000000000。 输入样例 3 3 输出样例 27 参考答案 #include<bits/stdc.h&…

企业级iptalbes防火墙

一、IPtables介绍 Iptables是unix/linux自带的一款开源的基于包过滤(对OSI模型的四层或者是四层以下进行过滤)的防火墙工具&#xff0c;它的功能十分强大&#xff0c;可以对流入和流出服务器的数据包进行很精细的控制。 iptables其实并不是真正的防火墙&#xff0c;我们可以把…

【AI绘画】全网最强midjourney使用方法!新手必收藏!!

手把手教你入门绘图超强的AI绘画程序Midjourney&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画。下面是Midjourney注册和使用的方法。给大家带来了全新保姆级教程资料包**&#xff08;文末可获取&#xff09;** 第一步&#xff1a; 先注册一个D…

10 sping核心技术验证(Validation) 数据绑定(Data Binding)

Validation Spring提供了一个Validator接口&#xff0c;您可以使用它来验证对象。Validator接口通过使用Errors对象来工作&#xff0c;以便在进行验证时&#xff0c;验证器可以向Errors对象报告验证失败public class Person {private String name;private int age;// the usua…

代码随想录算法训练营第三天| LeetCode203.移除链表元素、707.设计链表、206.反转链表

文章目录 一、203. 移除链表元素感受代码二、707.设计链表感受代码206.反转链表感受总结一、203. 移除链表元素 感受 我对这道题。从理论上来说太熟悉了。咸鱼讲数据结构常用的方法他都会讲。但是我没上机没写过。到后面上机还是写不出来。giao。 代码 第一次写,想说一下,…

Blazor中使用impress.js

impress.js是什么&#xff1f; 你想在浏览器中做PPT吗&#xff1f;比如在做某些类似于PPT自动翻页&#xff0c;局部放大之类&#xff0c;炫酷无比。 官方示例直接放到Blazor中是不可用的。几经尝试&#xff0c;用以下方法可以实现。 &#xff08;写文不易&#xff0c;请点赞、…