mysql 创建索引 强制_mysql 强制走索引

2023-11-17

查询是数据库技术中最常用的操作。查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的SQL语句后, 执行这条SQL语句,然后将查询到的结果返回给客户端。虽然过程很简单,但不同的查询方式和数据库设置,对查询的性能将会有很在的影响。

因此,本文就在MySQL中常用的查询优化技术进行讨论。讨论的内容如:通过查询缓冲提高查询速度;MySQL对查询的自动优化;基于索引的排序;不可达查询的检测和使用各种查询选择来提高性能。

一、 通过查询缓冲提高查询速度

一般我们使用SQL语句进行查询时,数据库服务器每次在收到客户端发来SQL后,都会执行这条SQL语句。但当在一定间隔内(如1分钟内),接到完 全一样的SQL语句,也同样执行它。虽然这样可以保证数据的实时性,但在大多数时候,数据并不要求完全的实时,也就是说可以有一定的延时。如果是这样的话,在短时间内执行完全一样的SQL就有些得不偿失。

幸好MySQL为我们提供了查询缓冲的功能(只能在MySQL 4.0.1及以上版本使用查询缓冲)。我们可以通过查询缓冲在一定程度上提高查询性能。

我们可以通过在MySQL安装目录中的my.ini文件设置查询缓冲。设置也非常简单,只需要将query_cache_type设为1即可。在设 置了这个属性后,MySQL在执行任何SELECT语句之前,都会在它的缓冲区中查询是否在相同的SELECT语句被执行过,如果有,并且执行结果没有过 期,那么就直接取查询结果返回给客户端。但在写SQL语句时注意,MySQL的查询缓冲是区分大小写的。如下列的两条SELECT语句:

SELECT * from TABLE1 SELECT * FROM TABLE1

上面的两条SQL语句对于查询缓冲是完全不同的SELECT。而且查询缓冲并不自动处理空格,因此,在写SQL语句时,应尽量减少空格的使用,尤其是在SQL首和尾的空格(因为,查询缓冲并不自动截取首尾空格)。

虽然不设置查询缓冲,有时可能带来性能上的损失,但有一些SQL语句需要实时地查询数据,或者并不经常使用(可能一天就执行一两次)。这样就需要把 缓冲关了。当然,这可以通过设置query_cache_type的值来关闭查询缓冲,但这就将查询缓冲永久地关闭了。在MySQL 5.0中提供了一种可以临时关闭查询缓冲的方法:

SELECT SQL_NO_CACHE field1, field2 FROM TABLE1

以上的SQL语句由于使用了SQL_NO_CACHE,因此,不管这条SQL语句是否被执行过,服务器都不会在缓冲区中查找,每次都会执行它。

我们还可以将my.ini中的query_cache_type设成2,这样只有在使用了SQL_CACHE后,才使用查询缓冲。

SELECT SQL_CALHE * FROM TABLE1

二、MySQL对查询的自动优化

索引对于数据库是非常重要的。在查询时可以通过索引来提高性能。但有时使用索引反而会降低性能。我们可以看如下的SALES表:

CREATE TABLE SALES

( ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, NAME VARCHAR(100) NOT NULL,

PRICE FLOAT NOT NULL, SALE_COUNT INT NOT NULL,

SALE_DATE DATE NOT NULL,

PRIMARY KEY(ID),

INDEX (NAME),

INDEX (SALE_DATE) );

假设这个表中保存了数百万条数据,而我们要查询商品号为1000的商品在2004年和2005年的平均价格。我们可以写如下的SQL语句:

SELECT AVG(PRICE) FROM SALES

WHERE ID = 1000 AND SALE_DATE BETWEEN ‘2004-01-01‘ AND ‘2005-12-31‘;

如果这种商品的数量非常多,差不多占了SALES表的记录的50%或更多。那么使用SALE_DATE字段上索引来计算平均数就有些慢。因为如果使 用索引,就得对索引进行排序操作。当满足条件的记录非常多时(如占整个表的记录的50%或更多的比例),速度会变慢,这样还不如对整个表进行扫描。因此,MySQL会自动根据满足条件的数据占整个表的数据的比例自动决定是否使用索引进行查询。

对于MySQL来说,上述的查询结果占整个表的记录的比例是30%左右时就不使用索引了,这个比例是MySQL的开发人员根据他们的经验得出的。然而,实际的比例值会根据所使用的数据库引擎不同而不同。

三、 基于索引的排序

MySQL的弱点之一是它的排序。虽然MySQL可以在1秒中查询大约15,000条记录,但由于MySQL在查询时最多只能使用一个索引。因此,如果WHERE条件已经占用了索引,那么在排序中就不使用索引了,这将大大降低查询的速度。我们可以看看如下的SQL语句:

SELECT * FROM SALES WHERE NAME = “name” ORDER BY SALE_DATE DESC;

在以上的SQL的WHERE子句中已经使用了NAME字段上的索引,因此,在对SALE_DATE进行排序时将不再使用索引。为了解决这个问题,我们可以对SALES表建立复合索引:

ALTER TABLE SALES DROP INDEX NAME, ADD INDEX (NAME, SALE_DATE)

这样再使用上述的SELECT语句进行查询时速度就会大副提升。但要注意,在使用这个方法时,要确保WHERE子句中没有排序字段,在上例中就是不能用SALE_DATE进行查询,否则虽然排序快了,但是SALE_DATE字段上没有单独的索引,因此查询又会慢下来。

四、 不可达查询的检测

在执行SQL语句时,难免会遇到一些必假的条件。所谓必假的条件是无论表中的数据如何变化,这个条件都为假。如WHERE value < 100 AND value > 200。我们永远无法找到一个既小于100又大于200的数。

如果遇到这样的查询条件,再去执行这样的SQL语句就是多此一举。幸好MySQL可以自动检测这种情况。如我们可以看看如下的SQL语句:

SELECT * FROM SALES WHERE NAME = “name1” AND NAME = “name2”

以上的查询语句要查找NAME既等于name1又等于name2的记录。很明显,这是一个不可达的查询,WHERE条件一定是假。MySQL在执行 SQL语句之前,会先分析WHERE条件是否是不可达的查询,如果是,就不再执行这条SQL语句了。为了验证这一点。我们首先对如下的SQL使用 EXPLAIN进行测试:

EXPLAIN SELECT * FROM SALES WHERE NAME = “name1”

上面的查询是一个正常的查询,我们可以看到使用EXPLAIN返回的执行信息数据中table项是SALES。这说明MySQL对SALES进行操作了。再看看下面的语句:

EXPLAIN SELECT * FROM SALES WHERE NAME = “name1” AND NAME = “name2”

我们可以看到,table项是空,这说明MySQL并没有对SALES表进行操作。

五、 使用各种查询选择来提高性能

SELECT语句除了正常的使用外,MySQL还为我们提供了很多可以增强查询性能的选项。如上面介绍的用于控制查询缓冲的SQL_NO_CACHE和SQL_CACHE就是其中两个选项。在这一部分,我将介绍几个常用的查询选项。

1. STRAIGHT_JOIN:强制连接顺序

当我们将两个或多个表连接起来进行查询时,我们并不用关心MySQL先连哪个表,后连哪个表。而这一切都是由MySQL内部通过一系列的计算、评估,最后得出的一个连接顺序决定的。如下列的SQL语句中,TABLE1和TABLE2并不一定是谁连接谁:

SELECT TABLE1.FIELD1, TABLE2.FIELD2 FROM TABLE1 ,TABLE2 WHERE …

如果开发人员需要人为地干预连接的顺序,就得使用STRAIGHT_JOIN关键字,如下列的SQL语句:

SELECT TABLE1.FIELD1, TABLE2.FIELD2 FROM TABLE1 STRAIGHT_JOIN TABLE2 WHERE …

由上面的SQL语句可知,通过STRAIGHT_JOIN强迫MySQL按TABLE1、TABLE2的顺序连接表。如果你认为按自己的顺序比MySQL推荐的顺序进行连接的效率高的话,就可以通过STRAIGHT_JOIN来确定连接顺序。

2. 干预索引使用,提高性能

在上面已经提到了索引的使用。一般情况下,在查询时MySQL将自己决定是否使用索引,使用哪一个索引。但在一些特殊情况下,我们希望MySQL只使用一个或几个索引,或者不希望使用某个索引。这就需要使用MySQL的控制索引的一些查询选项。

限制使用索引的范围

有时我们在数据表里建立了很多索引,当MySQL对索引进行选择时,这些索引都在考虑的范围内。但有时我们希望MySQL只考虑几个索引,而不是全部的索引,这就需要用到USE INDEX对查询语句进行设置。

SELECT * FROM TABLE1 USE INDEX (FIELD1, FIELD2) …

从以上SQL语句可以看出,无论在TABLE1中已经建立了多少个索引,MySQL在选择索引时,只考虑在FIELD1和FIELD2上建立的索引。

限制不使用索引的范围

如果我们要考虑的索引很多,而不被使用的索引又很少时,可以使用IGNORE INDEX进行反向选取。在上面的例子中是选择被考虑的索引,而使用IGNORE INDEX是选择不被考虑的索引。

SELECT * FROM TABLE1 IGNORE INDEX (FIELD1, FIELD2) …

在上面的SQL语句中,TABLE1表中只有FIELD1和FIELD2上的索引不被使用。

强迫使用某一个索引

上面的两个例子都是给MySQL提供一个选择,也就是说MySQL并不一定要使用这些索引。而有时我们希望MySQL必须要使用某一个索引(由于 MySQL在查询时只能使用一个索引,因此只能强迫MySQL使用一个索引)。这就需要使用FORCE INDEX来完成这个功能。

SELECT * FROM TABLE1 FORCE INDEX (FIELD1) …

以上的SQL语句只使用建立在FIELD1上的索引,而不使用其它字段上的索引。

3. 使用临时表提供查询性能

当我们查询的结果集中的数据比较多时,可以通过SQL_BUFFER_RESULT.选项强制将结果集放到临时表中,这样就可以很快地释放MySQL的表锁(这样其它的SQL语句就可以对这些记录进行查询了),并且可以长时间地为客户端提供大记录集。

SELECT SQL_BUFFER_RESULT * FROM TABLE1 WHERE …

和SQL_BUFFER_RESULT.选项类似的还有SQL_BIG_RESULT,这个选项一般用于分组或DISTINCT关键字,这个选项通知MySQL,如果有必要,就将查询结果放到临时表中,甚至在临时表中进行排序。

SELECT SQL_BUFFER_RESULT FIELD1, COUNT(*) FROM TABLE1 GROUP BY FIELD1

六、 结论

在程序设计中同样存在一个“二八原则”,即20%的代码用去了80%的时间。数据库应用程序的开发亦然。数据库应用程序的优化,重点在于SQL的执行效率。而数据查询优化的重点,则是使得数据库服务器少从磁盘中读数据以及顺序读页而不是非顺序读页。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql 创建索引 强制_mysql 强制走索引 的相关文章

  • [vue-router] uncaught error during route navigation

    vue路由在加载组件之前会执行一些逻辑 尤其是生命周期的钩子函数 如果你在以上的钩子函数中 写了自己的逻辑 并报错了 就会触发 vue router uncaught error during route navigation这个错误 原因
  • 基于upload-labs的文件上传漏洞总结

    普通的前端绕过 1 抓包 2 上传jpg等格式的木马文件 3 bp上改回php后缀即可 普通绕过 1 抓包 2 上传jpg等格式的木马文件 3 bp上改后缀名为将后缀改为 php3 php4 php5 phtml等等 大小写绕过 即后缀名改
  • minikube命令

    Basic Commands 0minikube version查看版本 1minikube start启动一个集群 minikube start vm driver none image repository registry cn ha
  • ei计算机投稿 知乎,知乎热议:科研有很水的idea应该发表出来吗?

    原标题 知乎热议 科研有很水的idea应该发表出来吗 科研有很水的idea应该发表出来吗 来源 https www zhihu com question 372648294 小伙伴们 对于只能发EI 水会 OA SCI期刊那种 自己看到都觉
  • k8s基本命令

    k8s命令 https kubernetes io zh docs tutorials kubernetes basics 官网地址 基本命令 查看节点服务器 kubectl get nodes 查看命名空间 kubectl get ns
  • kettle(一)kettle介绍

    kettle介绍及组成 一 kettle 是什么 kettle 是一个ETL工具 ETL Extract Transform Load 数据抽取 转换 装载 kettle 是java编写 绿色无需安装 抽取高效稳定 kettle 主要用来对
  • 【零知ESP8266教程】快速入门5-使用按键来控制你的灯

    上节课 我们已经学习了如何制作一个简易交通灯 那么如何去控制一个LED的亮或者灭呢 此次试验采用按键来控制我们的LED 实现LED的简单控制 一 工具原料 电脑 windows系统 ESP8266开发板 micro usb线 LED灯一个
  • (模板)多项式乘法对任意数取模

    多项式乘法 系数对MOD 1000000007取模 常数巨大 慎用 只要选的K个素数乘积大于MOD MOD N 理论上MOD可以任取 define MOD 1000000007 define K 3 const int m K 100453
  • ajax怎么渲染数据,ajax数据请求渲染

    JQuery引入 html JS function var url https api douban com v2 movie search q E4 B8 89 E4 BD 93 count 1 ajax method get url d
  • 数据结构——第五章树(详细知识点总结)

    知识框架 5 1 树的基本概念 5 1 1 树的定义 树是n n gt 0 个节点的有限集 当n 0时 称为空树 在任意一棵非空树中应满足 有且仅有一个特定的称为根 Root 的结点 当n gt 1时 其余结点可分为m m gt 0 个互不
  • ArcGIS Maritime Server 开发教程(八)ArcGIS Bathymetry 扩展模块

    ArcGIS Maritime Server 开发教程 八 ArcGIS Bathymetry 扩展模块 本章导读 ArcGIS Bathymetry 扩展是 ArcGIS Maritime 解决方案中用于管理水深的重要模块 与传统的离散点
  • 内网穿透FRP详细教程

    简介 frp 是一个专注于内网穿透的高性能的反向代理应用 支持 TCP UDP HTTP HTTPS 等多种协议 可以将内网服务以安全 便捷的方式通过具有公网 IP 节点的中转暴露到公网 通过在具有公网 IP 的节点上部署 frp 服务端
  • 【笔记】构造函数的私有、公有、特权、静态成员

    根据书 javascript DOM高级程序设计 一书整理的笔记 var Myconstuctor function name 特权成员 与私有方法不同 特权方法能够被公开访问 而且还能够访问私有成员 特权方法是指在构造函数的作用域中使用t
  • 玩转wsl2之环境搭建

    Windows是市场占有率最高的桌面操作系统 很多开发人员还是习惯于在Windows系统中进行开发工作 但服务器领域多采用Linux操作系统 因此开发人员在开发过程中 经常会遇到windows系统开发的软件难以部署到Linux系统的问题 W
  • HTML表格嵌套、合并表格

    一 表格元素 lt table gt table常用属性 border 边框像素 width height 表格宽度 高度 bordercolor 表格边框颜色 bgcolor 表格背景颜色 二 tr th td元素 th和td元素是在tr
  • linux学习笔记-安装配置使用clamav杀毒软件

    1 安装clamav 2 更新病毒库 freshclam 如果更新不了 或者更新特别慢 可以手动下载病毒库文件 放到 var lib clamav 文件下 在更新病毒库 病毒库文件链接 三个文件 bytecode cvd http data
  • Python面试题,通过代码获取nginx.log中状态码的出现次数

    先用pyton分析nginx的一行日志 通过split函数把日志变成一个用空格分开的列表 得到了状态码是在索引为8的列表元素 开始操作 打开nginx日志文件 定义一个空字典 用来存放状态码出现的次数 结合while循环遍历每行日志
  • Python面试,这16个问题你一定要熟知

    一 Python 是如何进行内存管理的 答 从三个方面来说 一对象的引用计数机制 二垃圾回收机制 三内存池机制 对象的引用计数机制 Python 内部使用引用计数 来保持追踪内存中的对象 所有对象都有引用计数 引用计数增加的情况 一个对象分
  • C++查看变量类型办法(typeinfo)

    一 类型含意 bool b char c signed char a unsigned char h signed short int s unsigned short int t signed int i unsigned int j s

随机推荐

  • 一文讲懂C#、ASP.NET、ASP.NET MVC、ASP.NET web form、asp.net core mvc的区别

    微软的命名很糟糕 技术上有两个框架 ASP NET和ASP NET Core 它们分别基于 NET Framework和 NET Core构建 当Microsoft首次尝试创建一个遵循MVC模式的 现代 Web应用程序平台时 它将这个新平台
  • 主合取/析取范式

    前置知识 简单合取 析取式 合取 析取范式 极小项 当存在n个命题变项做合取时 如果这个简单合取式出现了全部的命题变项或它的否定形式 且恰好只出现一次 则这个式子属于极小项 以n 3 命题变项为p q r为例 他们的极小项如表 主析取范式
  • Ubuntu16升级为18

    https blog csdn net sean 8180 article details 81075659
  • 从mimikatz抓取密码学习攻防

    前不久在使用mimikatz抓取hash的时候遇到了报错 本着追根溯源的原则去查看了mimikatz抓取密码的原理 在学习的过程中发现了mimikatz的每种报错都有不同的原因 本文就从mimikatz的防御角度出发来分析如何防御mimik
  • 【ubuntu】报错su:认证失败

    问题 ubuntu使用su命令时提示认证失败 解决方法 报这个错误的原因是root用户默认锁定的 只要使用passwd命令重新设置下root密码即可 详细步骤 1 命令行输入sudo passwd 2 根据提示修改密码 3 输入su 4 输
  • Altium Designer编辑PCB时,器件跑出可视界面外的解决方法

    很多人在使用AD等进行PCB设计的时候 由于制作封装问题或者是其他操作问题 会遇到在PCB界面下某一个或者几个封装超出软件显示范围 不论如何移动和放大缩小 都无法显示出来 也就没法选中和编辑 下面就讲讲如何解决这个问题 一个封装超出界外 不
  • Feign 使用 @SpringQueryMap 来解决多参数传递问题

    本文目录 1 Feign传递一个bean对象参数 2 Feign传递一个bean对象参数 多个基本类型参数 3 Feign传递多个基本类型参数 4 Feign传递多个bean对象参数 在实际项目开发过程中 我们使用 Feign 实现了服务与
  • css_流光按钮(转载)

    CSS部分 初始化 取消页面的内外边距 padding 0 margin 0 body 弹性布局 让页面元素垂直 水平居中 display flex justify content center align items center 让页面
  • Mock框架应用(三)-Mock Post请求

    不带参数的post请求 description 不含参数的post请求 request uri post method post response text 不含参数的post请求 带参数的post请求 配置Json 并启动moco服务 d
  • python列表index找不到索引_Python list.index在找不到索引时抛出异常

    Why does list index throw an exception instead of using an arbitrary value for example 1 What s the idea behind this To
  • R语言数据清洗与规整-回归模型为例

    数据清洗和规整是进行数据分析的前提条件 数据的清洗和规整通常会花费比进行数据分析更多的时间 正所谓 清洗一小时 分析五秒钟 数据清洗和规整要依据实际数据的特征进行 其包括缺失值和冗余值的处理 数据重归类 字符类型转换等 这里将使用 狗熊会
  • Opencv C++ 基本数据结构 Mat

    Opencv C 基本数据结构 Mat Mat 构造单通道Mat对象 获取单通道Mat的基本信息 以三行两列的矩阵为例 1 获取行数和列数 2 使用成员函数size 获取矩阵的尺寸 3 使用成员函数channels 获取矩阵的通道数 4 使
  • Unity中的GameObjectRecorder类录制动画

    Unity中的GameObjectRecorder类录制动画 记录 GameObjectRecorder 示例代码 解析 记录 首先是 参考及示例视频 Unity制作战神等级的表情动画 游戏 CG Vtuber适用 相关代码在8分16秒之后
  • 进程间通信(IPC)

    概述 进程间通信就是在不同进程之间传播或交换信息 那么不同进程之间存在着什么双方都可以访问的介质呢 进程的用户空间是互相独立的 一般而言是不能互相访问的 唯一的例外是共享内存区 另外 系统空间是 公共场所 各进程均可以访问 所以内核也可以提
  • 用javaScript编写lrc歌词解析器

    如果想要了解如何编写的请继续往下看 如果只需要代码 请点击这里Github lrc歌词文件介绍 来先看一下以下歌词 Heart To Heart lrc ti Heart To Heart ar James Blunt al Heart T
  • Python Socket连接过程详析

    一 套接字 套接字是为特定网络协议 例如TCP IP ICMP IP UDP IP等 套件对上的网络应用程序提供者提供当前可移植标准的对象 它们允许程序接受并进行连接 如发送和接受数据 为了建立通信通道 网络通信的每个端点拥有一个套接字对象
  • TinyDDS编程实践

    背景 传统计算机网络的运行依赖于集中式运营商及服务提供商 Server 它在拓扑结构上的典型特点就是存在一个或数个 中心节点 整个网络的数据传输和处理都集中在少数节点上 中心节点 是维持整个系统运行的关键 也是控制整个系统运行的中枢 这种拓
  • springboot集成alibaba-druid数据连接池及配置

    一 pom文件中引入依赖
  • 【TensorFlow】tf.nn.conv2d卷积实现+filter计算原理

    本来想转载底层实现过程的 结果发现原文中的实验2错误 在这里说明下fliter工作过程 输入层 就是输入的图像 有可能是三通道的有可能是单通道的 filter 深度与输入层的深度 通道数 相同 输出层 输出层的就是filter遍历输入层后的
  • mysql 创建索引 强制_mysql 强制走索引

    查询是数据库技术中最常用的操作 查询操作的过程比较简单 首先从客户端发出查询的SQL语句 数据库服务端在接收到由客户端发来的SQL语句后 执行这条SQL语句 然后将查询到的结果返回给客户端 虽然过程很简单 但不同的查询方式和数据库设置 对查