当前位置: 首页 > news >正文

mysql一个小问题引发的思考-mysql类型转换-查询缓存 及 MYSQL查询缓存以及自动选择不使用查询缓存的情况

一、mysql一个小问题引发的思考-mysql类型转换-查询缓存

    最近在做的一个项目中有一个SQL语句发现点问题,大概如下:

select * from table where cid=0 or find_in_set('1', cid);

    数据表中的字段cid是字符串类型,原来的后端同学未提过此字段还能是空值(原认为只有0或者ID值的组合,以逗号分开),测试期间也未有空值,上线后发现这个字段还能是空值,导致出现一些问题,即数据库中字段为空的内容也被查询出来:

    原因和解决:此字段是字符串类型,不能使用数字查询。所以改起来到是很简单,查询条件里的cid=0加上引号即可解决。

    但深入一下:使用上面不带引号的SQL查询到底发生了什么呢?实际上发生的东西和PHP也有点类似,就是mysql类型转换typecasting/conversion,不带引号查询时MYSQL会将表中的值转为数字后再进行比对。因此数据表中的空值,字符串(当然这里不会出现),0三种结果都会出来。如下图测试示例:

    问题就到这里就结束了吗?没有,我在将两条SQL进行对比的时候发现,差异还不只是这点。对比的两条SQL和查询用时如下:

[SQL]
select * from has where ids=2;
受影响的行: 0
时间: 0.173s
[SQL]
select * from has where ids='2';
受影响的行: 0
时间: 0.165s

    单从这一次执行来看,并未有很大的差别,我重复这样操作了多遍,有时两个SQL的用时消耗是一样的,即在类型转换上的开销并不大。当然也不能忽略,高并发时这点性能提升也很关键。总之通过这个对比可以发现增加类型转换是会增加系统开销的。接下来,执行完第一次后再执行两句SQL,这时的用时如下:

[SQL]
select * from has where ids=2;
受影响的行: 0
时间: 0.157s
[SQL]
select * from has where ids='2';
受影响的行: 0
时间: 0.001s

    此时会发现和上面的结果大相径庭,加了引号的SQL执行用时快了很多,基本是不消耗时间。为什么后面的这句SQL能这么快呢?原因也很简单,就是使用上了SQL的查询缓存,而前面这句未使用上查询缓存,如果我们把上面的SQL语句改成下面两句,就会发现它们的性能相差较小(带上引号执行会更快):

select SQL_NO_CACHE * from has where ids=2;
select SQL_NO_CACHE * from has where ids='2';

    所以从上面可以看出,如果条件不带上引号,性能损失远不止一点点,因为不带引号每次都是重新查库,不能使用查询缓存,而带上了引号后面的查询都很快(数据表没有变化的前提下)。由此也可以说这不是一个小问题。对全局都很重要。而且写SQL时也一定要规避这样的问题。

    那为什么不带引号就不能使用查询缓存呢?我们在执行这句SQL时再接着执行一句show warnings;:

select * from has where ids=2;
show warnings;
#show warnings;的结果如下:
Warning	1292	Truncated incorrect DOUBLE value: 'a'
Warning	1292	Truncated incorrect DOUBLE value: '23,12'

    可见在执行不带引号的SQL时,MYSQL发生了警告信息。像PHP一样,只是因为这个不影响功能,不会导致严重错误。但发生了警告对查询缓存是非常关键的。mysql对存在警告信息的查询语句无法缓存其记录集。即永远不能使用查询缓存。

    所以一句话:对mysql中的字符串字段的判断条件一定要带上引号!

二、MYSQL查询缓存以及自动选择不使用查询缓存的情况

    MYSQL查询缓存(5.1.17开始支持)顾名思义,只是针对查询的缓存功能。在WEB开发甚至社会各种生活的方方面面,都是缓存为王。MYSQL层也不例外,
    MYSQL查询缓存功能缓存的是SELECT操作或预处理查询的SQL语句和结果集;新的SELECT语句或预处理查询语句,先去查询缓存(根据整条SQL),判断是否存在可用的记录集,注意SQL语句必须是完全一样,SQL有改变大小写或者加上某个空格也会导致查询缓存不可用。即使完全相同的SQL,如果使用不同的字符集、不同的协议等也会被认为是不同的查询而分别进行缓存。

1. MYSQL查询缓存的启用

    启用mysql查询缓存涉及两个配置:query_cache_type和query_cache_size,任何一个参数设置为0都是查询缓存功能不可用。如果确实要关闭查询缓存,请设置query_cache_type为0,可减少检查query_cache_size的配置。

        query_cache_type: 有0、1、2三个取值。0则不使用查询缓存。1表示始终使用查询缓存。2表示按需使用查询缓存。 如果query_cache_type为1而又不想利用查询缓存中的数据,可以用下面的SQL: 

    SELECT SQL_NO_CACHE * FROM my_table WHERE condition;
    如果值为2,要使用缓存的话,需要使用SQL_CACHE开关参数:
    SELECT SQL_CACHE * FROM my_table WHERE condition;

    可以通过命令查看查询缓存命中次数: SHOW STATUS LIKE 'Qcache_hits';

    query_cache_size:允许设置query_cache_size的值最小为40K,对于最大值则可以几乎认为无限制,实际生产环境的应用经验告诉我们,该值并不是越大,查询缓存的命中率就越高,也不是对服务器负载下降贡献大,反而可能抵消其带来的好处,甚至增加服务器的负载,至于该如何设置,下面的章节讲述,推荐设置 为:64M;

    query_cache_limit:限制查询缓存区最大能缓存的查询记录集,可以避免一个大的查询记录集占去大量的内存区域,而且往往小查询记录集是最有效的缓存记录集,默认设置为1M,建议修改为16k~1024k之间的值域,不过最重要的是根据自己应用的实际情况进行分析、预估来设置;
query_cache_min_res_unit:设置查询缓存分配内存的最小单位,要适当地设置此参数,可以做到为减少内存块的申请和分配次数,但是设置过大可能导致内存碎片数值上升。默认值为4K,建议设置为1k~16K

    query_cache_wlock_invalidate:该参数主要涉及MyISAM引擎,若一个客户端对某表加了写锁,其他客户端发起的查询请求,且查询语句有对应的查询缓存记录,是否允许直接读取查询缓存的记录集信息,还是等待写锁的释放。默认设置为0,也即允许。在表的结构或数据发生改变时,查询缓存中的数据不再有效。比如INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE会导致缓存数据失效。所以查询缓存适合有大量相同查询的应用,不适合有大量数据更新的应用。对于一些并不是要经常查询的数据库,可以使用query_cache_type=2模式,然后SQL语句加SQL_CACHE参数指定,以减少查询缓存的开销。

2. MYSQL自动不使用查询缓存的情况:

即便开启了MYSQL查询缓存,但在以下条件下MYSQL会自动选择不使用查询缓存:

1,查询缓存对什么样的查询语句,无法缓存其记录集,大致有以下几类:
2,查询语句中加了SQL_NO_CACHE参数;
3,查询语句中含有获得值的函数,包涵自定义函数,如:CURDATE()、GET_LOCK()、RAND()、CONVERT_TZ等;
4,对系统数据库的查询:mysql、information_schema
5,查询语句中使用SESSION级别变量或存储过程中的局部变量;
6,查询语句中使用了LOCK  IN SHARE MODE、FOR UPDATE的语句
7,查询语句中类似SELECT …INTO 导出数据的语句;
8,事务隔离级别为:Serializable情况下,所有查询语句都不能缓存;
9,对临时表的查询操作;
10,存在警告信息的查询语句;例见:http://47.93.183.36/article/343.html
11,不涉及任何表或视图的查询语句;
12,某用户只有列级别权限的查询语句;

3. 查询缓存区的碎片整理

    查询缓存使用一段时间之后,都会出现内存碎片,为此需要监控相关状态值,并且定期进行内存碎片的整理和清理维护

1、FLUSH QUERY CACHE; //清理查询缓存内存碎片。
2、RESET QUERY CACHE; //从查询缓存中移出所有查询。
3、FLUSH TABLES; //关闭所有打开的表,同时该操作将会清空查询缓存中的内容。

相关文章:

mysql一个小问题引发的思考-mysql类型转换-查询缓存 及 MYSQL查询缓存以及自动选择不使用查询缓存的情况

一、mysql一个小问题引发的思考-mysql类型转换-查询缓存 最近在做的一个项目中有一个SQL语句发现点问题,大概如下: select * from table where cid0 or find_in_set(1, cid); 数据表中的字段cid是字符串类型,原来的后端同学未提过此字段还能是…...

css更改图片颜色

css更改图片颜色&#xff0c;比较时候颜色单一的图片&#xff0c;比如logo之类的 css中的 filter 属性定义元素&#xff08;通常是 <img>&#xff09;的视觉效果&#xff08;如模糊和饱和度&#xff09; img{ -webkit-filter: invert(51%) sepia(94%) saturate(6433%) h…...

通过POST请求往Elastic批量插入数据

文章目录 引言I 请求文档请求参数请求例子引言 调试工具:Apifox 需求: 向Elasticsearch中的’test_index’索引批量插入文档 情况认证: Basic Auth 在 Header 添加参数 Authorization,其值为在 Basic 之后拼接空格,以及经过 Base64 编码的 {{Username}}:{{Password}} 示…...

JAW:一款针对客户端JavaScript的图形化安全分析框架

关于JAW JAW是一款针对客户端JavaScript的图形化安全分析框架&#xff0c;该工具基于esprima解析器和EsTree SpiderMonkey Spec实现其功能&#xff0c;广大研究人员可以使用该工具分析Web应用程序和基于JavaScript的客户端程序的安全性。 工具特性 1、动态可扩展的框架&#x…...

错误解决 error CS0117: ‘Buffer‘ does not contain a definition for ‘BlockCopy‘

Unity 2022.3.9f1 导入 Runtime OBJ Importer 后出现&#xff1a; error CS0117: ‘Buffer’ does not contain a definition for ‘BlockCopy’ 解决办法&#xff1a; 源代码&#xff1a; int DDS_HEADER_SIZE 128; byte[] dxtBytes new byte[ddsBytes.Length - DDS_HEAD…...

ICMPv6与DHCPv6之网络工程师软考中级

ICMPv6概述 ICMPv6是IPv6的基础协议之一。 在IPv6报文头部中&#xff0c;Next Header字段值为58则对应为ICMPv6报文。 ICMPv6报文用于通告相关信息或错误。 ICMPv6报文被广泛应用于其它协议中&#xff0c;包括NDP、Path MTU发现机制等 ICMPv6控制着IPv6中的地址自动配置、地址…...

【HTML — 构建网络】HTML 入门

在本文中,我们将介绍 HTML 的绝对基础知识。为了帮助您入门,本文定义了元素、属性以及您可能听说过的所有其他重要术语。它还解释了这些在 HTML 中的位置。您将学习 HTML 元素的结构、典型的 HTML 页面的结构以及其他重要的基本语言功能。在此过程中,也将有机会玩转 HTML! …...

javafx的ListView代入项目的使用

目录 1. 创建一个可观察的列表&#xff0c;用于存储ListView中的数据,这里的User是包装了用户的相关信息。 2.通过本人id获取friendid&#xff0c;及好友的id&#xff0c;然后用集合接送&#xff0c;更方便直观一点。 3.用for遍历集合&#xff0c;逐个添加。 4.渲染器&…...

基于ABAP OLE技术实现对服务器文件进行读写操作

使用ABAP中的OLE&#xff08;Object Linking and Embedding&#xff09;技术&#xff0c;可以实现对服务器文件的读写操作。以下是一个示例&#xff0c;演示如何通过ABAP代码使用OLE自动化对象来读写服务器上的文件。这里主要以Excel文件的读写操作为例。 1. 读Excel文件 代码…...

求教Postgresql在jdbc处理bit(1)字段的预处理解决方案

文章目录 1.建表语句&#xff1a;2.使用以下方式的预处理方式都报错了3.可以先用sql拼接实现功能 1.建表语句&#xff1a; CREATE TABLE public.h_user (id serial4 not null,username varchar(50) NULL,"password" varchar(64) NULL,nickname varchar(60) NULL,ema…...

微信小程序-自定义tabBar

通过官网给出的示例自己实现了自定义的tabBar&#xff0c;但结果发现 无法监听页面生命周期函数 结语&#xff1a;原想的是实现不一样的效果&#xff08;如下&#xff09; 故尝试了自定义tabBar&#xff0c;虽然做出来了&#xff0c;但也发现这个做法存在不足&#xff1a; 在…...

vue3+element-plus 实现动态菜单和动态路由的渲染

在 Vue.js 中&#xff0c;使用 Vue Router 管理路由数据&#xff0c;并将其用于渲染 el-menu&#xff08;Element UI 的菜单组件&#xff09;通常涉及以下几个步骤&#xff1a; 定义路由元数据&#xff1a; 在你的路由配置中&#xff0c;为每个路由项添加 meta 字段&#xff0c…...

GO-学习-03-基本数据类型

数据类型&#xff1a;基本数据类型和复合数据类型 基本数据类型&#xff1a;整型、浮点型、布尔型、字符串 复合数据类型&#xff1a;数组、切片、结构体、函数、map、通道&#xff08;channel&#xff09;、接口 整型&#xff1a; package main import "fmt" im…...

高并发场景下,系统的保护机制

伴随着分布式&#xff0c;微服务项目的快速发展。各个微服务的调用和通讯难免会出现依赖关系&#xff0c;如果上游服务在依赖下游服务的时候下游服务出现了故障从而导致下游服务的不可用&#xff0c;进一步导致了上游的服务被拖垮&#xff0c;就会发生服务雪崩&#xff0c;故障…...

服务器构建私有npm库(Docker + Verdaccio)

npm官网有时候因为网络原因包推不上去&#xff0c;那就简单构建个私有库 私有库不会被共享&#xff0c;且配置不需要太高1h2G就行 1.需要安装Docker&#xff0c;这个跳过了 2.生成配置文件 mkdir /home/verdaccio cd /home/verdaccio mkdir conf && mkdir storage &am…...

LabVIEW做二次开发时应该注意哪些方面?

在使用LabVIEW进行二次开发时&#xff0c;以下几个方面需要特别注意&#xff1a; 需求明确化&#xff1a; 确认并详细记录客户的需求&#xff0c;明确系统的功能、性能、可靠性等要求。制定详细的需求文档&#xff0c;并与客户反复确认&#xff0c;避免后期的需求变更和误解。 …...

docker配置上网代理获取镜像

一、添docker子配置档设置 1、创建目录 mkdir /etc/systemd/system/docker.service.d 2、创建http-proxy.conf文件,增加以下内容 cat > /etc/systemd/system/docker.service.d/http-proxy.conf <<EOF [Service] Environment“HTTP_PROXYhttp://192.168.0.2:8118…...

SqlSugar删除没有定义主键的实体类对应的数据库表数据

一般而言&#xff0c;使用SqlSugar的DbFirst功能创建数据库表实体类时&#xff0c;如果数据库表有主键&#xff0c;生成的实体类对应属性也会标识为主键&#xff0c;如下图所示。   但有时候生成的实体类没有自动配置主键&#xff0c;这时可以通过以下方式进行删除操作&…...

虚拟机复制后网络不可用,报错“network.service - LSB: Bring up/down networking”

查询IP地址&#xff0c;eth33 没有显示IP地址 尝试重启&#xff0c;有报错&#xff0c;并且有提示&#xff0c;按照提示执行下看看 解决办法 chkconfig NetworkManager offsystemctl disable NetworkManager.serviceservice NetworkManager stopservice network restart 之后检…...

Redis 7.x 系列【30】集群管理命令

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 集群信息2.1 CLUSTER INFO 3. 节点管理3.1 CLUSTER MYID3.2 CLUSTER NODES3…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...