这里是用来发现慢sql的一个好方法 --by.阿丹
Prometheus-监控Mysql进阶用法(1)(安装配置)_一单成的博客-CSDN博客
阿丹:
知道了慢sql的语句那么就开始按照优化步骤对sql进行排查和优化。
1、阅读sql逻辑
首先观察sql语句的书写,整理sql的逻辑。
分别sql查询层级。
2、使用explain查看执行计划
在按照执行计划中的参数来进行优化:
(1)根据type来进行优化
在MySQL中,explain
命令提供了有关查询执行计划的详细信息,其中type
列描述了查询的访问方法。在type
列中,从高到低,常见的访问方法级别包括:
-
system
:这是最高级别的访问方法,通常只会有一条记录,表示表只有一行。例如,对于查询全局变量的操作,MySQL可能使用system
级别。 -
const
:这表示查询在表中只匹配一行数据,通常是由于使用了主键或唯一索引进行精确匹配。 -
eq_ref
:在连接查询中,这是最有效的访问方法之一,表示在连接时表之间的关联是基于一个唯一索引。 -
ref
:表示使用非唯一索引进行查询,返回匹配某个值的多个行。 -
fulltext
:这表示使用全文索引进行查询。 -
ref_or_null
:类似于ref
,但还包括返回NULL值的行。 -
index_merge
:表示使用多个索引进行查询,并通过合并结果来获得最终的结果。 -
unique_subquery
:这表示在子查询中使用了唯一索引来查询。 -
index_subquery
:类似于unique_subquery
,但是使用的是非唯一索引。 -
range
:表示使用索引范围进行查询,例如使用BETWEEN
或IN
操作符。 -
index
:这表示全索引扫描,即遍历整个索引树。 -
all
:这是最低级别的访问方法,表示全表扫描,即遍历整个表。
请注意,这些查询访问方法并非严格按照从高到低的顺序,而是根据查询的特点和优化器的决策来确定的。不同的查询可能会使用不同的访问方法。
注意:
最少是要在range以上才能够达到上生产环境的条件。
优化措施-加索引
注意:索引失效的原因排查
在 MySQL 中,索引可能会失效的几个常见原因包括:
-
数据较少:如果表中的数据量较小,索引可能会变得不那么有效,因为对于小表而言,全表扫描可能比使用索引更快。
-
不适当的索引选择:选择不当的索引类型或未正确地创建适合查询的索引,可能导致索引失效。例如,当查询涉及到对索引列进行函数操作,或者使用
OR
操作符连接多个条件时,索引可能无法被有效利用。 -
字符串列过长:如果使用了较长的字符串列作为索引,未能适当地截断或使用前缀索引,也可能导致索引失效。
-
数据分布不均匀:如果表中的数据分布不均匀,某些索引可能会较少覆盖查询条件,导致索引失效。
-
统计信息过期:MySQL 使用统计信息来决定如何使用索引,如果统计信息过期或不准确,优化器可能无法正确地选择合适的索引,导致索引失效。
-
查询使用了函数操作:当查询使用函数操作时,例如对索引列进行函数操作或使用函数作为查询条件,索引可能无法被有效利用,导致索引失效。
-
隐式数据类型转换:如果查询中的条件类型与索引列的数据类型不匹配,MySQL 会进行隐式的数据类型转换,导致索引失效。
-
看添加索引的列是不是参与了计算。
为了避免索引失效,需要正确地设计和创建索引,并根据查询的特点进行优化。此外,定期更新统计信息,避免使用函数操作或隐式数据类型转换,也有助于提高索引的效率和准确性。
使用sql语句创建索引
CREATE INDEX 索引名 ON 表名(对应表中的列);
它创建了一个普通索引。在 MySQL 中,可以使用以下语句来创建不同类型的索引:
-
普通索引(Normal Index):使用
CREATE INDEX
语句来创建。例如:CREATE INDEX index_name ON table_name(column_name);
-
唯一索引(Unique Index):使用
CREATE UNIQUE INDEX
语句来创建。例如:CREATE UNIQUE INDEX index_name ON table_name(column_name);
-
主键索引(Primary Key Index):使用
ALTER TABLE
语句来添加主键。例如:ALTER TABLE table_name ADD PRIMARY KEY (column_name);
-
全文索引(Full-Text Index):使用
ALTER TABLE
语句来添加全文索引。例如:ALTER TABLE table_name ADD FULLTEXT(column_name);
-
聚簇索引(Clustered Index):聚簇索引在 MySQL 中是通过主键索引实现的,通过创建主键自动创建聚簇索引。
CREATE CLUSTERED INDEX idx_clustered_index_name
ON table_name (column1, column2, ...);
就你的具体示例而言,CREATE INDEX idx_orders_date ON orders(orderdate);
创建了一个普通索引,名称为 idx_orders_date
,用于 orders
表上的 orderdate
列。
要创建索引,你可以使用 CREATE INDEX
语句,指定索引名称、表名和要建立索引的列名。确保你在建立索引时考虑查询的需要和数据的分布,以便获得最佳的查询性能。
重构sql语句
场景一:
原:
改:
如图因为在之前的sql中即便是创建了索引但是还是因为参与了函数计算所以导致索引的失效,那么这里就使用更改sql语句书写的方式来将该列拿出来。
同时注意使用聚簇索引来避免回表就可以了。
避免回表
使用覆盖索引->在创建索引的时候直接将需要的数据的列直接与索引绑定,这样在指针寻找的时候就可以直接找到相应的数据来避免回表。
在执行计划中,可以在possible_keys属性中看到,有相关的索引,然后在key属性中可以看到具体使用的索引。
(2)根据Extra发现问题
在 EXPLAIN
查询结果中,属性 Extra
提供了关于执行计划中其他相关信息的附加细节。它可以提供有关查询执行过程中发生的特定操作或优化选项的信息。 Extra
属性通常用于说明执行计划中的一些重要细节或特殊情况。
以下是一些常见的 Extra
属性及其含义:
- Using index: 表示查询使用了覆盖索引,即查询只通过索引就可以返回所需的数据,而无需进一步访问表本身。
- Using where: 表示查询使用了 WHERE 子句进行条件过滤。
- Using temporary: 表示查询需要创建一个临时表来处理查询中的某些操作,如排序或分组。
- Using filesort: 表示查询需要对结果进行排序,但无法通过索引完成排序,因此需要使用文件排序算法。
- Using join buffer (Block Nested Loop): 表示查询使用了连接缓冲区(BNL)算法来处理连接操作。
- Using index condition: 表示查询使用了索引条件推送优化,即在索引上进行条件过滤。
这些只是一些常见的 Extra
属性,实际上还有其他可能的属性值,具体取决于数据库管理系统和查询的复杂性。理解 Extra
属性可以帮助您分析查询的执行计划并识别潜在的性能问题或优化机会。
针对属性的值优化思路:
根据 Extra
属性的信息,您可以考虑以下优化方法:
-
Using index: 如果查询使用了覆盖索引,这通常是一个好的迹象。确保相应的列上有适当的索引,并检查索引的覆盖程度是否满足查询需求。
-
Using where: WHERE 子句用于条件过滤,这有助于减少返回结果集的大小。确保相关列上有合适的索引,以提高条件过滤的效率。
-
Using temporary: 创建临时表可能会对性能产生影响。考虑优化查询或调整查询结构,例如使用更有效的语句或重写查询,以避免临时表的创建。
-
Using filesort: 文件排序操作可能会消耗大量计算资源。尽量通过优化查询或添加适当的索引来避免文件排序。可以考虑调整查询的 ORDER BY 语句,以便能够使用索引完成排序操作。
-
Using join buffer (Block Nested Loop): 使用连接缓冲区(BNL)算法进行连接操作,但对于大型数据集可能会导致性能下降。在性能较差的情况下,可以尝试使用其他连接算法或调整查询中的连接条件。
-
Using index condition: 索引条件推送优化可以提高查询性能。确保查询中的条件与索引的列匹配,并且索引的选择性较高。
此外,您还可以考虑以下通用的优化方法来提高查询性能:
- 确保适当的索引存在,并根据查询需求创建或调整索引。
- 对表进行分区或分片,以减少查询的数据量。
- 优化查询语句,避免不必要的复杂性和重复操作。
- 使用批量操作或合并多个查询以减少数据库访问次数。
- 监控数据库的性能,并根据需要进行调整和优化。
最佳的优化策略取决于具体的数据库、表结构和查询模式。因此,在进行任何优化之前,建议先进行基准测试和性能分析,以了解具体的瓶颈和问题所在,然后有针对性地采取相应的优化措施。