文章851
标签121
分类10

Mysql索引合并: 一条sql可以使用多个索引

MySQL索引合并:一条SQL可以使用多个索引

引言

在MySQL数据库中,索引是提高查询性能的关键因素。通常情况下,一条SQL语句只能使用一个索引来加速查询。然而,在某些情况下,MySQL的查询优化器可以使用多个索引来执行查询操作,这被称为索引合并。本文将介绍索引合并的概念、使用场景和注意事项,并探讨其在提升查询性能方面的作用。

1. 索引合并概述

索引合并是指MySQL查询优化器在执行查询时,同时使用多个索引来满足查询条件的过程。通过合并多个索引,查询优化器可以更有效地定位符合查询条件的数据,从而提高查询性能。

2. 索引合并的使用场景

索引合并通常在以下两种情况下发生:

2.1 联合索引合并

当一个查询条件涉及到多个列,并且这些列中的每一列都有单独的索引时,MySQL查询优化器可以通过联合索引合并来加速查询。例如,考虑以下查询语句:

SELECT * FROM table_name WHERE column1 = value1 AND column2 = value2;

如果column1column2分别有单独的索引,查询优化器可以合并这两个索引,以减少数据的扫描并快速定位符合条件的行。

2.2 范围查询合并

当一个查询条件涉及到一个范围查询(例如大于、小于或区间查询),并且这个范围查询可以由多个索引覆盖时,MySQL查询优化器可以通过合并这些索引来提高查询性能。例如,考虑以下查询语句:

SELECT * FROM table_name WHERE column1 > value1 AND column2 < value2;

如果column1column2分别有单独的索引,并且这两个索引可以覆盖查询条件,查询优化器可以合并这两个索引,以减少数据的扫描并快速定位符合条件的行。

3. 索引合并的注意事项

在使用索引合并时,需要注意以下几点:

  • 索引合并的效果取决于查询的具体情况和数据分布。在一些情况下,索引合并可能带来性能提升,但在其他情况下可能并不明显。因此,对于具体的查询,需要进行测试和评估。
  • 索引合并可能增加查询优化器的计算成本。当查询条件涉及到多个索引时,查询优化器需要评估多种索引合并的组合方式,并选择最优的执行计划。这可能会增加查询的优化时间。
  • 索引合并的效果与索引的选择性相关。选择性是指索引中不重复的值的比例。如果索引的选择性较低,即索引中的重复值较多,那么索引合并的效果可能不明显。

4. 总结

索引合并是MySQL查询优化器的一个重要功能,它可以在某些情况下使用多个索引来提高查询性能。通过联合索引合并和范围查询合并,查询优化器可以更有效地定位符合查询条件的数据。

但需要注意的是,索引合并的效果取决于具体的查询和数据分布。在实际应用中,需要对索引合并进行测试和评估,以确保它对查询性能的提升是有效的。

希望本文对您理解MySQL索引合并的概念和使用场景有所帮助,并能在提升查询性能方面提供指导。

引用文献:

请注意,上述博客是Markdown格式,您可以将其保存为.md文件,并使用适当的Markdown编辑器进行编辑和格式化。同时,请根据您的实际情况和风格要求进行必要的调整和修改。

引用的文献是MySQL 8.0版本的官方文档,其中提供了关于多列索引和索引合并的详细说明。您可以在该文档中深入了解索引合并的原理和使用方法。

TCP端口状态说明ESTABLISHED、TIME_WAIT、 CLOSE_WAIT

一. 首先说下tcp端口的几种状态:

1、LISTENING状态

FTP服务启动后首先处于侦听(LISTENING)状态。

2、ESTABLISHED状态

ESTABLISHED的意思是建立连接。表示两台机器正在通信。

3、CLOSE_WAIT

对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭

4、TIME_WAIT

我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAITTCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分 段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情 况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。
目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socketLINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误。

5、SYN_SENT状态

SYN_SENT状态表示请求连接,当你要访问其它的计算机的服务时首先要发个同步信号给该端口,此时状态为SYN_SENT,如果连接成功了就变为 ESTABLISHED,此时SYN_SENT状态非常短暂。但如果发现SYN_SENT非常多且在向不同的机器发出,那你的机器可能中了冲击波或震荡波 之类的病毒了。这类病毒为了感染别的计算机,它就要扫描别的计算机,在扫描的过程中对每个要扫描的计算机都要发出了同步请求,这也是出现许多 SYN_SENT的原因。

二、如发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,

vim /etc/sysctl.conf

编辑文件,加入以下内容:

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

然后执行 /sbin/sysctl -p 让参数生效。

time_wait 的设计,是基于tcp的四次挥手,上面改的那些内核参数的修改并非一劳永逸,可以参考:系统调优,你所不知道的TIME_WAITCLOSE_WAIT

开发 Swoole 服务 使用端口问题

最近开发新项目 服务端口5w 起 , 但是总是出现端口被占用...

我一直都用 netstat -tunple |grep -i 56904 检索 但并没有搜索到.

找了运维同学看了下 使用 netstat -an |grep 56904

Xnip2024-02-28_09-49-37.png
如上图 netstat -an |grep 56904 , 返回 ESTABLISHED, 破案了

Linux上,有一个sysctl参数ip_local_port_range,可用于定义网络连接可用作其源(本地)端口的最小和最大端口的限制,同时适用于TCPUDP连接。

我新增服务的端口,在ip_local_port_range区间端口内, 本机其他服务进程与其他网络服务构成建立网络连接. 端口我就用不了了.

自定义服务端口 不要在ip_local_port_range 范围内.

诶 问题比较低级, 收录下

Mysql 表中某字段所有值转换为小写(或大写)

代码如下:

转换为小写:
UPDATE 表名 SET 列名= lower( 列名 );

如果转换为大写:
UPDATE 表名 SET 列名= UCASE( 列名 );

Redis持久化相关问题 ISCONF Redis is configured to save RDB snapshots

服务器抛错, redis 持久化出了问题. 抛错如下:

Fatal error: Uncaught RedisException: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error

翻译:

(错误)MISCONF Redis 已配置为保存 RDB 快照,但目前无法在磁盘上持久化。 可以修改数据集的命令被禁用,因为如果 RDB 快照失败(stop-writes-on-bgsave-error 选项),此实例被配置为在写入期间报告错误。 有关 RDB 错误的详细信息,请检查 Redis 日志。
抛错中 已经提供了解决方案 stop-writes-on-bgsave-error 参数调整为 no;

这个问题19年也是发生过的, 解决方案 Redis抛错:MISCONF Redis is configured to save RDB snapshots, but it is currently not able to.

下面找了个介绍的文章内容比较细.

Redis 可以将数据库快照保存在名为dump.rdb的二进制文件中。
RDB这种持久化方式被称为快照。

工作方式:

Redis调用forks,获得子进程 子进程将数据集写入到一个临时RDB文件中
当子进程完成对新RDB文件的写入时,Redis用新RDB文件替换原来的文件,并删除旧的RDB文件
这种工作方式使得Redis可以从copy-on-write机制中获益。(AOF的重写也利用了写时复制)
写时复制 是一种计算机程序设计领域的优化策略。核心思想是,如果有多个调用者同时要求相同资源,他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的。此作法主要的优点是如果调用者没有修改该资源,就不会有副本被创建,因此多个调用者只是读取操作时可以共享同一份资源。

其实stop-writes-on-bgsave-error 在配置文件里在 快照 板块里。

默认情况下,如果启用了 RDB 快照(至少一个保存点)并且最新的后台保存失败,``将停止接受写入。
这将使用户意识到(以一种艰难的方式)数据没有正确地保存在磁盘上,否则很可能没有人会注意到并且会发生一些灾难。
如果后台保存过程将再次开始工作,Redis 将自动允许再次写入。
但是,如果您设置了对 Redis 服务器和持久性的适当监控,您可能希望禁用此功能,以便 Redis 继续照常工作,即使存在磁盘、权限等问题。

所以说简单将该选项设置为no很可能依然没有从本质上解决问题, 只是说就算发生错误我也依然备份。
其实在持久化出错时停止工作也是一种保护机制和提示。

我之后又将stop-writes-on-bgsave-error 设置为了yes, 但是再次加入KEY的时候, 没有报错。

理论上应该要看日志, 但是我这里大概可以猜测到应该是和内存有关, 因为我的服务器只有4G的内存, 大概是一时之间起了好几个程序, 内存空间不够fork的子进程

即使我有很多空闲 RAM,在 Linux 下后台保存也会因 fork() 错误而失败!
简短的回答:echo 1 > /proc/sys/vm/overcommit_memory:)

现在是长的:

Redis 后台保存模式依赖于现代操作系统中 fork 的写时复制语义:Redis fork(创建子进程)是父进程的精确副本。子进程将数据库转储到磁盘上并最终退出。理论上,子进程应该使用与作为副本的父进程一样多的内存,但实际上由于大多数现代操作系统实现的写时复制语义,父进程和子进程将共享公共内存页面。只有在子页面或父页面发生变化时,页面才会被复制。由于理论上所有页面都可能在子进程保存时发生变化,Linux 无法提前知道子进程将占用多少内存,因此如果overcommit_memory 设置为零 fork 将失败,除非有足够多的可用 RAM 来真正复制所有父内存页面,结果是如果您有 3 GB 的 Redis 数据集和只有 2 GB 的可用内存,它将失败。

设置overcommit_memory为 1 告诉 Linux 放松并以更乐观的分配方式执行 fork,这确实是Redis 想要的。

原文地址 : https://blog.csdn.net/qq_43178138/article/details/119144986

">