侧边栏壁纸
博主头像
gale-blog博主等级

少年一贯快马扬帆,道阻且长不转弯,要盛大,要绚烂,要哗然,要用理想的泰坦尼克号去撞现实冰川,要当烧赤壁的风,而非借箭草船,要为了一片海,就肯翻万山

  • 累计撰写 39 篇文章
  • 累计创建 5 个标签
  • 累计收到 5 条评论

目 录CONTENT

文章目录

SQL优化

二月在这里
2024-01-27 / 0 评论 / 0 点赞 / 61 阅读 / 5254 字

慢SQL优化,避免慢SQL

识别慢查询

使用像MySQL的慢查询日志这样的工具来识别执行时间长的查询。一旦您识别出这些查询,您可以开始分析它们以确定缓慢的根本原因。

  1. 打开MySQL配置文件my.cnf或my.ini。

  1. 找到[mysqld]部分,并添加以下行:

  slow_query_log = 1
​
  slow_query_log_file = /var/log/mysql/mysql-slow.log
​
  long_query_time = 2
​
​

这将启用慢查询日志,并将慢查询日志文件设置为/var/log/mysql/mysql-slow.log。longquerytime参数设置为2,这意味着执行时间超过2秒的查询将被记录在慢查询日志中。

3.重新启动MySQL服务器以使更改生效。

4.分析慢查询日志以识别执行时间长的查询。您可以使用像pt-query-digest这样的工具来分析慢查询日志并生成报告。

优化查询

有几种方法可以优化SQL查询,包括添加索引、重写查询和优化表结构。

-1. 使用索引:索引可以通过允许数据库快速定位您正在查找的数据来显着加速查询执行。您可以在经常在WHERE子句、JOIN条件和ORDER BY子句中使用的列上创建索引。但是,要小心不要创建太多的索引,因为这可能会减慢INSERT、UPDATE和DELETE操作的速度。

-2. 避免使用SELECT *:不要从表中选择所有列,只选择您实际需要的列。这可以减少需要从磁盘读取和通过网络传输的数据量,从而提高查询性能。

-3. 明智地使用子查询和连接:子查询和连接可以是查询数据的强大工具,但如果使用不当,它们也可能很慢。尽量避免在SELECT子句中使用子查询,因为这可能导致子查询对结果集中的每一行执行。相反,将子查询用作WHERE子句或派生表。此外,要小心不要连接太多的表,因为这可能会导致需要处理大量中间结果。

-4. 使用EXPLAIN分析查询:EXPLAIN语句可用于分析MySQL如何执行查询。这可以帮助您识别性能瓶颈并相应地优化查询。

-5. 启用查询缓存:MySQL具有查询缓存,可以将频繁执行的查询结果存储在内存中。这可以显着加速查询执行,特别是对于读取密集型工作负载。但是,要小心不要缓存经常更新的查询,因为这可能导致返回过时的数据。

优化表结构

优化表结构可以改善查询性能。例如,您可以将表拆分为更小的表,或者将冗余数据移动到单独的表中。使用缓存:使用缓存可以减少需要执行的查询数量。您可以使用像Redis这样的内存数据库来存储经常访问的数据。

  1. 规范化数据:规范化是将数据库中的数据组织成一致且易于管理的过程。这涉及将大型表拆分为更小、更易于管理的表,并在它们之间创建关系。通过这样做,您可以减少数据冗余并提高查询性能。

  2. 使用适当的数据类型:为每个列选择正确的数据类型可以对查询性能产生重大影响。例如,使用较小的数据类型,如INT而不是BIGINT,可以减少存储数据所需的磁盘空间和内存量,从而提高查询性能。

  3. 使用分区:分区将大型表分成更小、更易管理的部分,称为分区。这可以通过允许数据库仅访问与特定查询相关的分区来提高查询性能。您可以根据一系列值(例如按日期)或分区键的哈希来分区表。

  4. 使用反规范化:虽然规范化通常是一个好的实践,但在某些情况下,反规范化可以提高查询性能。反规范化涉及向表中添加冗余数据以避免昂贵的连接。这对于经常查询但很少更新的表格非常有用。

索引建立的几个原则

  1. 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(><betweenlike)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

  2. =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。

  3. 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录。

  4. 索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)。

  5. 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可

美团:SQL优化工具SQLAdvisor开源

SQLAdvisor 是由美团点评公司北京DBA团队开发维护的 SQL 优化工具:输入SQL,输出索引优化建议。 它基于 MySQL 原生词法解析,再结合 SQL 中的 where 条件以及字段选择度、聚合条件、多表 Join 关系等最终输出最优的索引优化建议。目前 SQLAdvisor 在公司内部大量使用,较为成熟、稳定。

SQLAdvisor架构流程图:


0

评论区