mysql中的explain居然也会骗人

直接甩张图,大家可以猜一下这个sql的执行时间

先提一嘴,bm表总共77条数据,而且没有大字段,字段数量也不多

在这里插入图片描述

explain中影响sql的关键

EXPLAIN 语句的输出中,影响 SQL 执行时间的关键项主要有以下几个:

  1. type(连接类型):

    • 这是执行计划中最重要的列之一,表示 MySQL 用于查找行的连接类型。常见的类型按效率排序为:
      • systemconst:单行查找,速度最快。
      • eq_refref:使用索引查找行,效率较高。
      • range:范围扫描,效率次于 ref
      • index:全索引扫描。
      • ALL:全表扫描,速度最慢。
    • 执行时间通常随着连接类型的效率降低而增加。
  2. rows(扫描行数):

    • 表示 MySQL 预计要读取的行数。行数越大,SQL 执行时间往往越长。通常通过优化查询条件和索引,可以减少扫描的行数。
  3. Extra(附加信息):

    • 这里包含了许多关于查询执行方式的附加信息,其中一些可能会影响执行时间:
      • Using index:表示查询仅使用了索引,效率较高。
      • Using where:表示使用了 WHERE 过滤条件。
      • Using temporary:使用临时表,通常会降低查询效率。
      • Using filesort:表示需要对结果进行排序,可能导致较长的执行时间。
  4. possible_keyskey(可能使用的索引与实际使用的索引):

    • possible_keys 列显示 MySQL 在执行查询时可以使用的所有索引。
    • key 列显示了实际使用的索引。如果 key 为空,则表示没有使用索引,通常会导致全表扫描,增加执行时间。
  5. filtered(过滤率):

    • 表示 MySQL 估计通过条件过滤后返回的行数百分比。值越低,表示更多的行被过滤,通常意味着更高效的查询。

通过这些项的分析,你可以更好地理解 SQL 查询的性能瓶颈,并进行优化以减少执行时间。

sql执行时间影响的因素

SQL 的执行时间受到多个因素的影响,包括硬件配置和数据库配置文件中的参数。以下是一些关键因素:

1. 硬件配置

  • CPU: 处理器的速度和核心数量直接影响SQL查询的计算速度。多核CPU可以提高并行查询的能力。
  • 内存(RAM): 足够的内存可以确保更多的数据被缓存,减少磁盘I/O,进而提高查询性能。
  • 磁盘 I/O 性能: 磁盘的读写速度(如使用SSD而非HDD)对处理大数据量的查询尤其重要。RAID配置和I/O调度策略也会影响性能。
  • 网络带宽: 在分布式数据库或远程数据库访问的场景中,网络带宽和延迟会影响SQL执行时间。

2. 数据库配置文件中的参数

  • 缓存和缓冲区大小:
    • innodb_buffer_pool_size (MySQL/InnoDB): 用于缓存数据和索引的缓冲池大小。更大的缓冲池可以减少磁盘I/O,提高性能。
    • shared_buffers (PostgreSQL): 控制数据库中共享缓冲区的大小,用于缓存数据块。
  • work_mem/sort_buffer_size: 这些参数决定了用于排序和哈希操作的内存大小。如果设置过小,数据库可能需要在磁盘上创建临时文件,增加I/O操作。
  • max_connections: 允许的最大并发连接数。过多的并发连接可能导致资源竞争,降低单个查询的性能。
  • query_cache_size (MySQL): 用于缓存查询结果的内存大小。对重复查询的系统有帮助,但在某些情况下可能会导致性能下降。
  • temp_buffer_size (PostgreSQL): 用于临时表的内存大小。增大这个值可以加快处理复杂查询的速度。
  • effective_cache_size (PostgreSQL): 这是一个估计值,告诉查询优化器系统的缓存大小,帮助优化器做出更好的决策。

3. 其他因素

  • 表和索引设计: 合理的表结构和索引设计可以显著减少查询时间。适当的索引有助于快速查找数据。
  • 查询优化器: 不同数据库有不同的查询优化器配置,影响查询计划的生成。适当调整优化器相关参数,可以改善SQL执行时间。
  • 并行查询: 某些数据库支持并行查询,相关的配置参数可以影响SQL查询如何在多个CPU核心上并行执行。

通过优化这些硬件和配置文件中的参数,可以显著提高SQL查询的执行性能。

总结开始的sql

  • 类型除了主表都是ref,说明效率已经是很高了
  • 扫描的行数,仅仅不超过100
  • extra展示使用了where,也不错了
  • possible_keyskey都存在值
  • 最后一项filtered表现不行,但是影响不会很大

所以这个sql应该是毫秒级别的,也就是肯定是一秒之内

可是结果为下图
在这里插入图片描述
所以:explain肯定是欺骗了我们,首先当一个字段可以是null,并且数量很大的时候,那么首先肯定是不走索引了,其实它的查询性能也会极大降低

null的利害

当查询条件中涉及 NULL 值和特定的字符串值时,即使在其他条件都没有变化的情况下,性能差异可以非常显著。这主要与数据库如何处理 NULL 值和具体值的索引有关。以下是详细的解释:

1. 索引的选择性

  • NULL

    • 选择性NULL 值通常具有较低的选择性,因为在表中可能有许多 NULL 值。索引的选择性指的是索引中能够区分不同记录的能力。对于 NULL 值,选择性较低,导致索引可能不如具体值的查询那么有效。
    • 索引存储:在许多数据库系统中,NULL 值的索引存储方式和非 NULL 值不同。处理 NULL 值的索引查询可能需要数据库扫描更多的记录或执行额外的逻辑,导致查询效率较低。
  • 具体字符串值

    • 选择性:当查询条件是一个具体的字符串值(如 'string'),索引的选择性通常较高,特别是当字段值的分布比较均匀或值相对唯一时。数据库能够通过索引快速定位到匹配的记录。
    • 索引利用:具体值的索引通常能够更高效地利用,因为索引可以直接定位到特定的值,从而减少扫描的记录数,提高查询速度。

2. 数据库索引处理

  • 处理 NULL

    • 索引扫描:在处理 NULL 值时,数据库系统可能需要扫描大量的记录来匹配 NULL 条件。如果字段中 NULL 值的比例较高,数据库可能会选择全表扫描或者低效的索引扫描。
    • 特殊处理:不同的数据库系统对 NULL 值的处理方式有所不同。在某些系统中,索引可能对 NULL 值的处理不如对具体值的处理高效。
  • 处理具体值

    • 直接匹配:当查询条件是具体的字符串值时,数据库可以通过索引快速找到匹配的记录。索引结构(如 B-树、哈希表等)能够高效地定位到特定值,从而提高查询速度。
    • 优化执行计划:数据库查询优化器通常会生成优化的执行计划来处理具体值的查询,利用索引减少扫描范围,从而提高查询效率。

3. 执行计划和性能

  • 执行计划

    • IS NULL 查询:执行计划可能需要处理复杂的逻辑来匹配 NULL 值,特别是当字段中 NULL 值较多时。执行计划可能选择全表扫描或低效的索引扫描。
    • 具体值查询:执行计划通常能够利用索引高效地定位到特定的字符串值,减少扫描范围,提高性能。
  • 查询性能

    • IS NULL:在字段中 NULL 值的比例较高时,查询可能变得较慢,因为数据库需要处理和匹配更多的 NULL 值。
    • 具体值:查询性能通常较好,因为数据库能够快速定位到具体的值,通过索引减少扫描的记录数。

示例说明

假设你的查询是:

SELECT * 
FROM your_table 
LEFT JOIN another_table 
ON your_table.id = another_table.id
WHERE your_table.some_field IS NULL;

和:

SELECT * 
FROM your_table 
LEFT JOIN another_table 
ON your_table.id = another_table.id
WHERE your_table.some_field = 'specific_value';
  • IS NULL:如果 your_table.some_field 中有大量 NULL 值,数据库可能需要扫描很多记录来找到匹配的 NULL 值,导致查询变慢。
  • 具体值:如果 your_table.some_field 中有很少的 'specific_value',数据库可以快速通过索引定位到这些记录,从而提高查询性能。

总结

  • NULL:通常具有较低的选择性,处理 NULL 值的查询可能效率较低,因为索引的利用效果较差。
  • 具体值:通常具有较高的选择性,索引能够更高效地支持具体值的查询,从而提升性能。

理解这些差异可以帮助优化查询性能,通过适当的索引设计和查询优化,能够显著提高数据库操作的效率。

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MySQL,使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而得知MySQL如何处理该查询语句。通过执行EXPLAIN语句,可以获取查询的执行计划信息,包括索引的使用情况、连接表的方式等,帮助选择更好的索引和编写更优化的查询语句。可以在SELECT语句之前增加EXPLAIN关键字,MySQL返回执行计划的信息,而不是实际执行该SQL语句。另外,EXPLAIN关键字还有一个变种叫做EXPLAIN EXTENDED,用于提供更详细的执行计划信息。如果你想查看更多关于EXPLAIN的详细信息,你可以参考MySQL官方文档关于EXPLAIN的说明。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [MySQL - Explain详解](https://blog.csdn.net/weixin_42201180/article/details/126122714)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [MySQL数据库:第十七章:Explain详解](https://blog.csdn.net/java_wxid/article/details/111881486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只牛博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值