Explain的简单使用

使用示例

场景:表记录了物联网传感器某段时间内的值。

首先创建一个数据库test_iot_base,然后创建一个存储传感器数据的表,名为senor_data,这里主要有的字段是id,type,timestamp,value。

sql 复制代码
CREATE TABLE sensor_data (
    id INT AUTO_INCREMENT PRIMARY KEY,
    device_id INT,
    sensor_type VARCHAR(50),
    value DECIMAL(10,2),
    timestamp TIMESTAMP
);

INSERT INTO sensor_data (device_id, sensor_type, value, timestamp) VALUES (123, 'soil_moisture', 45.67, NOW());
INSERT INTO sensor_data (device_id, sensor_type, value, timestamp) VALUES (456, 'temperature', 25.3, NOW());
INSERT INTO sensor_data (device_id, sensor_type, value, timestamp) VALUES (789, 'light_intensity', 1200.5, NOW());

获取特定传感器类型在某个时间段内的数据,并按照时间戳排序

sql 复制代码
SELECT * FROM sensor_data WHERE sensor_type = 'temperature' AND timestamp BETWEEN '2024-09-01' AND '2024-09-30' ORDER BY timestamp;

使用分析工具explain来分析,发现possible_keys没有使用索引,keys也没有使用索引。row表明查询的行数比较多,type字段值为all,还使用了额外的排序。效率比较低!。

创建一个索引

sql 复制代码
CREATE INDEX idx_sensor_type_timestamp ON sensor_data (sensor_type, timestamp);

再次使用explain分析刚刚的查询,发现possible_keyskey使用了刚刚创建的索引,type字段值变成range。row表名查询的行数只有1。

优化

可以通过分析explain的字段找到性能瓶颈。

一、分析 type 字段

  1. consteq_refrefrangeindexALL 的性能依次递减。

    • 如果是 ALL,代表全表扫描,这通常是性能最差的情况,说明没有合适的索引可用。例如,对于一个包含大量数据的表,如果查询没有使用索引,就会进行全表扫描,这会消耗大量的时间和资源。

    • range 表示使用索引进行范围扫描,比全表扫描要好很多,但如果范围过大,也可能会影响性能。比如,查询一个时间范围内的数据,如果时间范围跨度很大,可能会导致扫描的索引范围较大,从而影响性能。

二、查看 possible_keyskey 字段

  1. 如果 possible_keysNULL,说明没有可使用的索引来优化这个查询。这时候需要考虑为查询中的条件字段添加合适的索引。

    • 例如在物联网场景中,查询特定传感器类型和时间段内的数据,如果没有为 sensor_typetimestamp 字段添加索引,就可能导致全表扫描。
  2. 如果 keyNULL,即使 possible_keys 有可用索引,也说明查询没有使用到索引。这可能是因为索引不适合当前的查询条件,或者查询优化器选择了其他执行计划。

    • 比如索引的选择性不高,即索引列中不同值的数量较少,查询优化器可能认为使用索引的成本比全表扫描还高,从而选择全表扫描。

三、观察 rows 字段

  1. rows 表示预计需要扫描的行数。这个数字越大,说明查询需要扫描的数据量越多,性能可能越差。

    • 如果 rows 的值很大,即使使用了索引,也可能因为扫描的行数过多而导致性能问题。这时候可以考虑进一步优化索引,或者调整查询条件,减少扫描的行数。

四、检查 Extra 字段

  1. Using filesort 表示需要额外的排序操作,这会消耗资源,尤其是在数据量大的情况下。

    • 例如,查询结果需要按照某个字段排序,如果没有合适的索引支持排序,就会出现 Using filesort。可以通过添加合适的索引来避免排序操作,或者在查询中尽量避免不必要的排序。
  2. Using temporary 表示需要使用临时表,这也会影响性能。通常是因为查询中包含了复杂的子查询、聚合函数或者排序操作,导致数据库需要创建临时表来处理数据。

    • 对于复杂的查询,可以考虑优化查询逻辑,或者分步骤进行查询,避免使用临时表。

添加索引的一些规则

  1. 选择经常在 WHEREORDER BYGROUP BY 子句中出现的字段。

    • 在物联网场景中,比如经常根据传感器类型(sensor_type)进行查询筛选,或者按照时间戳(timestamp)进行排序,那么这两个字段就很适合作为索引字段。
    • 如果经常按照设备 ID(device_id)进行分组统计设备数据,那么 device_id 也应该考虑添加索引。
  2. 选择高选择性的字段。

    • 选择性是指字段中不同值的数量与总行数的比例。比例越高,选择性越好。例如,一个字段只有两个可能的值,那么它的选择性就很低;而一个字段包含大量不同的值,选择性就很高。
  3. 对于经常用于排序的字段,可以考虑创建升序或降序索引。

相关推荐
Passion不晚1 小时前
Spring Boot 入门:解锁 Spring 全家桶
spring boot·后端·spring
蜡笔小流2 小时前
Flask 第六课 -- 路由
后端·python·flask
怪人细胞2 小时前
【远程调用PythonAPI-flask】
后端·python·flask
代码吐槽菌2 小时前
基于SpringBoot的在线点餐系统【附源码】
java·开发语言·spring boot·后端·mysql·计算机专业
X² 编程说3 小时前
14.面试算法-字符串常见算法题(三)
java·数据结构·后端·算法·面试
请不要叫我菜鸡4 小时前
Go语言基础学习02-命令源码文件;库源码文件;类型推断;变量重声明
linux·后端·golang·类型推断·短变量·变量重声明·库源码文件
AskHarries4 小时前
Spring Boot集成Akka Cluster快速入门Demo
java·spring boot·后端·akka
少喝冰美式5 小时前
【大模型教程】如何在Spring Boot中无缝集成LangChain4j,玩转AI大模型!
人工智能·spring boot·后端·langchain·llm·ai大模型·计算机技术
lucifer3115 小时前
Spring Boot 中的配置属性绑定机制详解
java·后端
cci5 小时前
Rust gRPC---Tonic教程
后端·rust·grpc