MySQL数据库索引失效的常见情况

MySQL数据库索引失效的常见情况

01 索引失效负面后果

  • 在MySQL数据库中,当索引失效时,可能会导致以下后果:

  • 全表扫描:如果索引失效,MySQL 可能会选择执行全表扫描来检索数据,这将导致性能下降,特别是对于大型数据表而言。

  • 低效的查询计划:索引失效可能导致 MySQL 优化器选择不合适的查询计划,无法充分利用索引,从而增加查询的执行时间和资源消耗。

  • 大量的磁盘I/O:由于全表扫描会导致大量的磁盘I/O操作,可能会影响系统的整体性能,并增加系统负担。

  • 内存消耗过高:全表扫描需要更多的内存用于存储查询结果集,如果数据量较大,可能导致内存消耗过高,甚至引起内存溢出问题。

  • 锁竞争:全表扫描可能导致更多的行级锁或表级锁的竞争,影响系统的并发性能,导致其他查询被阻塞。

  • 查询延迟:由于索引失效导致查询性能下降,用户可能面临更长的查询响应时间,降低了系统的实时性。

  • 系统负载增加:全表扫描和低效的查询计划会增加系统的负载,可能导致系统响应变慢甚至崩溃

02 索引失效的原因

  • 索引失效通常是由于数据库查询优化器无法有效地使用索引来加速查询操作,造成查询性能下降的情况。

03 常见的索引失效的原因

  • 查询条件不匹配索引
    • 当查询条件中未使用索引列,或者使用了索引列但不是最左前缀时,索引将无法被利用,导致索引失效。
  • 对索引列进行运算或函数操作
    • :如果在查询条件中对索引列进行了运算、函数操作或类型转换,会导致索引失效,因为无法直接匹配索引列的值。
  • 使用通配符搜索
    • 在查询条件中使用通配符搜索(如以 % 开头的LIKE语句),会导致索引失效,因为通配符在索引列前会导致无法命中索引。
  • OR条件
    • 当查询条件中包含 OR 运算符连接多个条件时,如果其中有一个条件无法使用索引,整个查询都无法利用索引,导致索引失效。
  • 数据类型不匹配:如果查询条件中的数据类型与索引列的数据类型不匹配,比如字符串和数字的比较,将导致索引失效。
  • NULL值处理
    • 使用 IS NULL 或 IS NOT NULL 进行查询时,索引可能会失效,因为对 NULL 值的处理可能使索引无法被利用。
  • 统计信息不准确
    • 如果表的统计信息不准确或过时,优化器可能会做出错误的决策,选择不合适的执行计划,导致索引失效。
  • 大数据量情况下索引失效
    • 在数据量非常大的表中,即使有索引,也可能由于数据分布不均匀等原因导致索引失效,无法提高查询性能。

04 深入理解上述索引失效的原因

1.查询条件不匹配索引:

  • 假设有一个包含以下字段的表 users

    • id (主键)

    • name

    • age

    • city

  • 如果我们在该表上创建了一个复合索引 (name, age),表示对 nameage 这两列创建了一个联合索引。

  • 现在,如果我们执行以下查询:

SELECT * FROM users WHERE age = 30;
  • 由于查询条件中只涉及 age 列,而索引是在 (name, age) 上建立的,这个查询将无法有效利用索引。因为索引是按照 (name, age) 的顺序存储数据的,而查询条件中并未使用索引的最左前缀 name,导致索引失效。

  • 为了让该查询能够有效利用索引,应该尽量让查询条件涉及索引的最左前缀,例如:

SELECT * FROM users WHERE name = 'Alice' AND age = 30;
  • 这样查询条件中就涉及到了索引的最左前缀 name,索引可以被有效利用,提高查询性能。

2.对索引列进行运算或函数操作:

  • 假设有一个包含以下字段的表 products

    • id (主键)

    • price

    • discount

  • 现在我们在 price 列上创建了一个索引。

  • 如果我们执行以下查询:

SELECT * FROM products WHERE price * (1 - discount) < 50;
  • 在这个查询中,对 price 列进行了运算 (price * (1 - discount)),这将导致索引失效。因为索引只包含原始的 price 值,而查询条件中涉及了对 price 的计算,无法直接匹配索引列的值。

  • 为了避免索引失效,应该尽量避免在查询条件中对索引列进行运算或函数操作。在这种情况下,可以考虑重构查询条件,将计算操作提前,例如:

SELECT * FROM products WHERE price < 50 / (1 - discount);
  • 通过将计算操作提前,使得查询条件直接和索引列进行匹配,可以有效利用索引,提高查询性能。

3.使用通配符搜索

  • 假设有一个包含以下字段的表 products

    • id (主键)

    • name

  • 现在我们在 name 列上创建了一个索引。

  • 如果我们执行以下查询:

SELECT * FROM products WHERE name LIKE '%apple';
  • 在这个查询中,使用了以 % 开头的通配符,即表示以 “apple” 结尾的所有产品。这种情况下,无法利用索引来加速查询,因为通配符 % 在索引列的开头,导致无法命中索引。

  • 为了避免索引失效,应该尽量避免在查询条件中使用以 % 开头的通配符。如果需要进行类似的模糊搜索,可以考虑将通配符放在结尾,例如:

SELECT * FROM products WHERE name LIKE 'apple%';
  • 这样可以使得索引能够有效地匹配查询条件,提高查询性能。

4.OR条件:

  • 假设有一个包含以下字段的表 products

    • id (主键)

    • category

    • price

  • 现在我们在 category 列和 price 列上分别创建了索引。

  • 如果我们执行以下查询:

SELECT * FROM products WHERE category = 'Electronics' OR price < 100;
  • 在这个查询中,包含了一个 OR 条件,其中一个条件是针对 category 列的等值匹配,另一个条件是针对 price 列的范围查询。由于这两个条件无法同时利用各自的索引,整个查询无法利用索引,导致索引失效。

  • 为了避免索引失效,可以考虑拆分查询条件并使用 UNION 操作符来合并结果,例如:

SELECT * FROM products WHERE category = 'Electronics'
UNION
SELECT * FROM products WHERE price < 100;
  • 通过拆分查询条件,使得每个子查询可以单独利用索引,提高查询性能。

5.数据类型不匹配:

  • 假设有一个包含以下字段的表 products

    • id (主键)

    • product_name (字符串类型)

    • product_code (整数类型)

  • 现在我们在 product_name 列和 product_code 列上分别创建了索引。

  • 如果我们执行以下查询:

SELECT * FROM products WHERE product_code = '123';
  • 在这个查询中,查询条件中的 product_code 是一个字符串,而索引列 product_code 是一个整数类型的列。由于数据类型不匹配,即使 product_code 存在索引,也无法被用来加速该查询,导致索引失效。

  • 为了避免索引失效,应该确保查询条件中的数据类型与索引列的数据类型相匹配。在这种情况下,可以将查询条件中的字符串转换为整数,例如:

SELECT * FROM products WHERE product_code = 123;
  • 通过确保数据类型匹配,可以有效利用索引来提高查询性能。

6.NULL值处理:

  • 假设有一个包含以下字段的表 customers

    • id (主键)
    • name (字符串类型)
    • email (字符串类型,允许存储NULL值)
  • 现在我们在 name 列和 email 列上分别创建了索引。

  • 如果我们执行以下查询:

SELECT * FROM customers WHERE email IS NULL;
  • 在这个查询中,我们要查找所有 email 列为 NULL 的记录。由于 NULL 值的特殊性,对 NULL 值的处理可能导致索引失效,使得查询无法利用索引加速。

  • 为了避免索引失效,可以考虑对 NULL 值进行特殊处理,例如使用 COALESCE 函数将 NULL 值替换为一个特定的值,然后再进行查询,如下所示:

sqlCopy CodeSELECT * FROM customers WHERE COALESCE(email, '') = '';
  • 通过将 NULL 值转换为一个非 NULL 的值,可以确保索引能够被有效利用,提高查询性能。

7.统计信息不准确:

  • 假设有一个包含以下字段的表 orders

    • id (主键)
    • customer_id (顾客ID,外键)
    • order_date (订单日期)
  • 现在假设我们在 customer_id 列和 order_date 列上分别创建了索引。

  • 如果我们执行以下查询:

    sqlCopy CodeSELECT * FROM orders WHERE customer_id = 123;
    
  • 在这个查询中,优化器会尝试根据统计信息来确定使用哪个索引,以获取最佳的执行计划。如果统计信息不准确或过时,优化器可能会做出错误的决策,选择了不合适的执行计划,导致索引失效。

  • 为了避免索引失效的情况,我们可以采取以下步骤进行更新:

    • 更新统计信息:定期使用数据库系统提供的统计信息更新功能,例如在 PostgreSQL 中使用 ANALYZE 命令,以确保系统中的统计信息是最新的、准确的。通过更新统计信息,优化器可以更好地估计数据分布和行数,从而选择更合适的执行计划。
    • 强制使用索引:在查询中可以使用提示或者强制指令,让优化器选择使用正确的索引。例如,在 PostgreSQL 中,可以使用 SET enable_seqscan TO off; 来禁用顺序扫描,强制使用索引。
    • 优化查询语句:确保编写的查询语句简洁明了,避免不必要的复杂性。可以通过优化查询语句的写法,让优化器更容易选择正确的执行计划。
-- 更新统计信息
ANALYZE orders;-- 强制使用索引
SET enable_seqscan TO off;-- 优化查询语句
SELECT * FROM orders WHERE customer_id = 123;
  • 通过这些优化措施,可以提高查询性能并避免索引失效的问题,使数据库系统更有效地处理查询请求。

8.大数据量情况下索引失效:

  • 当数据量非常大时,即使存在索引,也可能出现由于数据分布不均匀等原因导致索引失效的情况。这种情况下,索引的选择性可能会降低,导致数据库优化器难以有效利用索引来加速查询。以下是一个简单的例子:

  • 假设有一个包含用户信息的表 users,其中有一个 gender 列表示用户的性别,现在我们在 gender 列上创建了一个索引。然而,在这个表中,男性用户和女性用户的数量相差非常悬殊,比如有99%的用户是男性,只有1%的用户是女性。

  • 如果我们执行以下查询:

    sqlCopy CodeSELECT * FROM users WHERE gender = 'Female';
    
  • 由于数据中绝大多数用户都是男性,数据库优化器可能认为使用索引并不高效,因为大部分数据都需要被检索,从而选择全表扫描而不是使用索引。这样就导致了索引在这种情况下的失效,无法提高查询性能。

  • 在这种情况下,可以考虑以下解决方案:

    • 重建索引:重新构建索引,可能采用不同的索引类型或调整索引列的顺序,以提高索引的选择性。
    • 优化查询:优化查询语句,避免不必要的条件或者限制,以减少不必要的数据访问。
    • 分区表:对表进行分区,根据实际情况将数据拆分到不同的分区中,可以提高查询效率。
    • 使用复合索引:考虑创建复合索引,覆盖更多的查询条件,以提高索引的利用率。
-- 创建复合索引
CREATE INDEX idx_gender_id ON users(gender, user_id);-- 优化查询语句
SELECT * FROM users WHERE gender = 'Female';

通过以上措施,可以在大数据量情况下更好地应对索引失效的问题,提高查询性能和系统效率。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue2 配置@指向src

使用的是vue cli创建的项目。 1.安装 path 如果在 Node.js 环境中运行代码&#xff0c;path 模块默认是可用的&#xff0c;则不需要单独安装&#xff0c;否则输入下面命令安装path npm i path -S 2.找到vue.config.js文件&#xff1a; const { defineConfig } require(vu…

辽渤湾海现已加入2024第七届燕窝天然滋补品博览会

参展企业介绍 大连辽渤湾海产品有限公司&#xff0c;是一家主营海参、鲍鱼、海胆等大连海产品的加工和销售的综合型水产企业&#xff0c;拥有国内精良的整条加工流水线&#xff0c;拥有上千平米的现代化加工办公场地的现代化企业。现已发展成为大连海参产品的主导型深加工基地。…

SpringBoot 三种拦截http请求方式Filter,Interceptor和AOP

1 Filter Filter常被叫做过滤器&#xff0c;filter的调用周期大致如下 也就是说filter在servlet之前&#xff0c;没有办法在filter中获取springboot中的java bean对象。 Filter生命周期方法 init:在服务器启动后&#xff0c;会创建Filter对象&#xff0c;然后调用init方法。…

Leetcode第27题:移除元素

代码实现 class Solution:def removeElement(self, nums: List[int], val: int) -> int:ent_removeTruewhile(ent_remove):if val in nums:nums.remove(val)else:ent_removeFalsereturn len(nums)思路:重复判断列表中是否存在目标值&#xff0c;存在则删除&#xff0c;直到…

无货源违规又现,现在还能做抖音小店吗?无货源商家该怎么调整?

大家好&#xff0c;我是电商花花。 最近好像又有很多人的店铺被查无货源违规&#xff0c;店铺还被扣12分&#xff0c;也申诉不了。 如果想要长期的做下去&#xff0c;就不要秀那些花里胡哨的操作&#xff0c;也不要为了短暂的自然流量而进行违规操作&#xff0c;为什么你的店…

【网络爬虫】(1) 网络请求,urllib库介绍

各位同学好&#xff0c;今天开始和各位分享一下python网络爬虫技巧&#xff0c;从基本的函数开始&#xff0c;到项目实战。那我们开始吧。 1. 基本概念 这里简单介绍一下后续学习中需要掌握的概念。 &#xff08;1&#xff09;http 和 https 协议。http是超文本传输&#xf…

leetcode mt simple

Leetcode-MT-Simple 文章实际写于2021年&#xff0c;那个炎热的夏天。 Leet Code 美团题库简单类总结&#xff0c;题目按照解法可大致分为数学法、计数法、位运算、双指针法、字符串、哈希表、栈、递归/迭代、排序法、匹配法、记忆化法、二分法、分治法、摩尔投票法、前缀和、…

基于nodejs+vue家装一体化平台python-flask-django-php

提高现下家装一体化平台的准确度&#xff0c;同时降低经济波动带来的不良影响&#xff0c;希望本文能对广大学者的研究提供参考。 前端技术&#xff1a;nodejsvueelementui, Express 框架于Node运行环境的Web框架, 语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&am…

喜获千万元价值补贴,探索 AI 领域新应用:Zilliz 全力支持 AI 初创企业

价值 1000 万元的大额补贴&#xff01;得到领先全行业的向量数据库团队支持&#xff01;尽享独家生态资源&#xff01;「Zilliz AI 初创计划」正式开启&#xff01; 「Zilliz AI 初创计划」是 Zilliz 面向 AI 初创企业推出的一项扶持计划&#xff0c;预计提供总计 1000 万元的 …

书生·浦语大模型实战营——两周带你玩转微调部署评测全链路

引言 人工智能技术的发展日新月异&#xff0c;其中大模型的发展尤其迅速&#xff0c;已然是 AI 时代最炙手可热的当红炸子鸡。 然而&#xff0c;大模型赛道对于小白开发者来说还是有不小的门槛。面对内容质量参差不齐的课程和实际操作中遇到的问题&#xff0c;许多开发者往往…

2核4g服务器能支持多少人访问?阿里云2核4g服务器在线人数

阿里云2核4G服务器多少钱一年&#xff1f;2核4G配置1个月多少钱&#xff1f;2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

C++语言学习(三)—— 文件操作

目录 一、文件操作 1.1 打开文件 1.2 关闭文件 1.3 读取文件 1.4 写入文件 1.5 文件指针 1.6 文件状态 1.7 其他文件操作 二、文件操作函数 2.1 打开文件函数 2.2 关闭文件函数 2.3 写入文件函数 2.4 读取文件函数 2.5 读取一行函数 2.6 获取文件大小函数 2.7 …

Java监听器模式在实际中的应用

监听器模式是一种行为型设计模式&#xff0c;它允许对象之间通过监听和触发事件的方式实现解耦&#xff0c;提高代码的灵活性和可维护性。在监听器模式中&#xff0c;存在两类角色&#xff1a;事件源&#xff08;Event Source&#xff09;和监听器&#xff08;Listener&#xf…

【PCL】mac下安装PCL的安装与配置

【PCL】mac下安装PCL的安装与配置 PCL PCL官方文档 PCL&#xff08;Point Cloud Library&#xff09;是在吸收了前人点云相关研究基础上建立起来的大型跨平台开源C编程库&#xff0c;它实现了大量点云相关的通用算法和高效数据结构&#xff0c;涉及到点云获取、滤波、分割、配…

从静态到动态化,Python数据可视化中的Matplotlib和Seaborn

​​本文分享自华为云社区《Python数据可视化大揭秘&#xff1a;Matplotlib和Seaborn高效应用指南》&#xff0c;作者&#xff1a; 柠檬味拥抱。 安装Matplotlib和Seaborn 首先&#xff0c;确保你已经安装了Matplotlib和Seaborn库。如果没有安装&#xff0c;可以使用以下命令…

知识图谱推理算法综述(上):基于距离和图传播的模型

背景 知识图谱系统的建设需要工程和算法的紧密配合&#xff0c;在工程层面&#xff0c;去年蚂蚁集团联合 OpenKG 开放知识图谱社区&#xff0c;共同发布了工业级知识图谱语义标准 OpenSPG 并开源&#xff1b;算法层面&#xff0c;蚂蚁从知识融合&#xff0c;知识推理&#xff…

底部填充胶在汽车电子领域的应用有哪些?

底部填充胶在汽车电子领域的应用有哪些&#xff1f; 在汽车电子领域&#xff0c;底部填充胶被广泛应用于IC封装等&#xff0c;以实现小型化、高聚集化方向发展。 底部填充胶在汽车电子领域有多种应用&#xff0c;包括以下方面&#xff1a; 传感器和执行器的封装&#xff1a;汽车…

AJAX(一):初识AJAX、http协议、配置环境、发送AJAX请求、请求时的问题

一、什么是AJAX 1.AJAX 就是异步的JS和XML。通过AJAX 可以在浏览器中向服务器发送异步请求&#xff0c;最大的优势&#xff1a;无刷新获取数据。AJAX 不是新的编程语言&#xff0c;而是一种将现有的标准组合在一起使用的新方式。 2.XML 可扩展标记语言。XML被设计用来传输和…

工业级POE交换机的SSH配置步骤

工业级POE交换机的SSH&#xff08;Secure Shell&#xff09;配置可以通过以下步骤进行&#xff1a; 1. 连接到POE交换机&#xff1a;使用一个支持SSH协议的终端工具&#xff08;如PuTTY&#xff09;连接到POE交换机的管理接口。 2. 登录到POE交换机&#xff1a;输入正确的用户…

详解Java 中的 Lambda 表达式

引言&#xff1a; Lambda 表达式是 Java 8 中引入的一个重要特性&#xff0c;它可以使代码更加简洁、易读&#xff0c;并且更加具有函数式编程风格。Lambda 表达式本质上是一个匿名函数&#xff0c;它可以作为方法参数传递&#xff0c;也可以直接赋值给一个变量。 一、Lambda 表…