博客
关于我
数据库优化 - SQL优化
阅读量:461 次
发布时间:2019-03-06

本文共 2696 字,大约阅读时间需要 8 分钟。

数据库优化从多个维度进行,针对SQL和系统性能都需要综合考虑。以下是针对SQL优化的详细探讨,结合实际案例说明优化方法和技巧。

判断问题SQL

判断SQL是否存在问题可以从以下两个方面进行分析:

系统级别的性能指标

系统级别的性能问题可能反映在以下方面:

  • CPU消耗严重:长时间占用CPU可能表明数据库查询过于复杂。
  • IO等待严重:磁盘读写时间过长会显著影响数据库性能。
  • 页面响应时间过长:用户操作响应变慢直接影响体验。
  • 应用日志中出现超时错误:数据库查询超时是常见问题。

可以通过使用sartop命令查看系统资源使用情况,或者借助Prometheus、Grafana等监控工具,实时监控系统状态。

SQL语句的结构分析

从SQL本身进行分析,主要关注以下方面:

  • 冗长的SQL语句:虽然难以直接判断性能问题,但长SQL通常难以维护,容易出错。
  • 执行时间过长:长时间执行的查询可能是瓶颈。
  • 全表扫描:执行计划中显示Type=ALLrows很大,通常意味着查询效率很低。

特别需要注意的是,执行计划中的key列显示ALL,这表明当前查询可能存在“坏味道”,需要优化。

获取问题SQL

针对不同数据库的慢查询日志获取方式:

MySQL

  • 慢查询日志:通过配置慢查询日志文件,记录执行时间过长的查询。
  • 测试工具:如loadrunner等,用于模拟并抓取慢查询。
  • 工具:如Percona公司的ptquery,专门用于分析慢查询。

Oracle

  • AWR报告:分析数据库活动报表,找到频繁执行的慢查询。
  • 内部视图:如v$sqlv$session_wait等,直接关联到慢查询。
  • 监控工具:如Grid Control,提供动态分析功能。

达梦数据库

  • AWR报告:类似于上述数据库。
  • 内部视图:如v$sqlv$session_wait等。
  • 性能监控工具:如DEM性能监控工具。

SQL编写技巧

编写高效的SQL语句需要遵循以下原则:

  • 合理使用索引

    • 索引的作用是提高查询效率,但过多索引会增加写操作负担。
    • 建立索引时,需考虑字段的重复值情况,选择率高且被频繁查询的字段建立索引。
    • JOIN字段通常需要索引,复杂文档类型查询建议使用全文索引。
  • 使用UNION ALL替代UNION

    • UNION ALL省去了排重和排序操作,效率更高。
  • 避免SELECT *

    • 避免使用SELECT *,因为优化器需要将其转换为具体字段查询,可能无法走覆盖索引。
  • JOIN字段建议建立索引

    • JOIN操作通常需要对字段进行查询优化,建立索引可以显著提升效率。
  • 避免复杂SQL

    • 简化复杂查询,必要时分解为多个简单查询。
  • 避免WHERE 1=1

    • 使用WHERE条件时,尽量避免1=1等固定值,直接写出真实条件更好。
  • 避免ORDER BY RAND()

    • 这种写法会导致数据列多次扫描,影响性能。
  • SQL优化实战

    通过实际案例分析,了解如何从系统和SQL两个层面进行优化。

    表结构

    CREATE TABLE `a` (    `id` int AUTO_INCREMENT,    `seller_id` bigint DEFAULT NULL,    `seller_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,    `gmt_create` varchar(30) DEFAULT NULL,    PRIMARY KEY (`id`));CREATE TABLE `b` (    `id` int AUTO_INCREMENT,    `seller_name` varchar(100) DEFAULT NULL,    `user_id` varchar(50) DEFAULT NULL,    `user_name` varchar(100) DEFAULT NULL,    `sales` bigint DEFAULT NULL,    `gmt_create` varchar(30) DEFAULT NULL,    PRIMARY KEY (`id`));CREATE TABLE `c` (    `id` int AUTO_INCREMENT,    `user_id` varchar(50) DEFAULT NULL,    `order_id` varchar(100) DEFAULT NULL,    `state` bigint DEFAULT NULL,    `gmt_create` varchar(30) DEFAULT NULL,    PRIMARY KEY (`id`));

    查询语句

    SELECT a.seller_id, a.seller_name, b.user_name, c.stateFROM a, b, cWHERE a.seller_name = b.seller_name  AND b.user_id = c.user_id  AND c.user_id = 17  AND a.gmt_create BETWEEN DATE_ADD(NOW(), INTERVAL –600 MINUTE) AND DATE_ADD(NOW(), INTERVAL 600 MINUTE)ORDER BY a.gmt_create;

    分析与优化

  • 数据量分析

    • 检查各表的数据量和索引情况,确认是否存在全表扫描。
  • 原执行时间

    • 通过测试工具测量当前查询的执行时间。
  • 原执行计划

    • 使用EXPLAIN命令获取执行计划,重点关注keyrows的值。
  • 优化思路

    • 字段类型一致性:确保user_id字段在bc表中与a表中的seller_id类型一致。
    • 创建索引:为user_idseller_name字段创建索引。
    • 复合索引:为包含多个字段的查询字段创建复合索引。
  • 优化步骤

    • 修改bc表的user_id字段为int类型。
    • user_id字段创建索引。
    • seller_name字段创建复合索引。
  • 优化效果

    • 优化后的查询执行时间显著减少,执行计划显示更多使用了索引。
  • 优化总结

  • 执行计划分析

    • 使用EXPLAIN工具详细分析查询执行计划,找出低效部分。
  • 告警信息处理

    • 定期查看数据库警告信息,及时修正潜在问题。
  • 索引策略

    • 根据查询模式和高频操作字段,合理设计索引结构。
  • 持续优化

    • 当优化效果不明显时,重复优化步骤,逐步调整和改进。
  • 通过以上方法,可以显著提升数据库性能,减少慢查询对业务的影响。

    转载地址:http://bouyz.baihongyu.com/

    你可能感兴趣的文章
    MySQL 查看有哪些表
    查看>>
    mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
    查看>>
    MySql 查询以逗号分隔的字符串的方法(正则)
    查看>>
    MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
    查看>>
    mysql 查询数据库所有表的字段信息
    查看>>
    【Java基础】什么是面向对象?
    查看>>
    mysql 查询,正数降序排序,负数升序排序
    查看>>
    MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
    查看>>
    mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
    查看>>
    mysql 死锁(先delete 后insert)日志分析
    查看>>
    MySQL 死锁了,怎么办?
    查看>>
    MySQL 深度分页性能急剧下降,该如何优化?
    查看>>
    MySQL 深度分页性能急剧下降,该如何优化?
    查看>>
    MySQL 添加列,修改列,删除列
    查看>>
    mysql 添加索引
    查看>>
    MySQL 添加索引,删除索引及其用法
    查看>>
    mysql 状态检查,备份,修复
    查看>>
    MySQL 用 limit 为什么会影响性能?
    查看>>
    MySQL 用 limit 为什么会影响性能?有什么优化方案?
    查看>>
    MySQL 用户权限管理:授权、撤销、密码更新和用户删除(图文解析)
    查看>>