Mysql优化神器(推荐)

前言

今天逛github时,发现了这款对 SQL 进行优化和改写的自动化工具sora。感觉挺不错的,就下载学习了一下。这个工具支持的功能比较多,可以作为我们日常开发中的一款辅助工具,现在我就把它推荐给你们~~~

github传送门:https://github.com/XiaoMi/soar

背景

在我们日常开发中,优化SQL总是我们日常开发任务之一。例行 SQL 优化,不仅可以提升程序性能,还能够降低线上故障的概率。

目前常用的 SQL 优化方式包括但不限于:业务层优化、SQL逻辑优化、索引优化等。其中索引优化通常通过调整索引或新增索引从而达到 SQL 优化的目的。索引优化往往可以在短时间内产生非常巨大的效果。如果能够将索引优化转化成工具化、标准化的流程,减少人工介入的工作量,无疑会大大提高我们的工作效率。

SOAR(SQL Optimizer And Rewriter) 是一个对 SQL 进行优化和改写的自动化工具。由小米人工智能与云平台的数据库团队开发与维护。

与业内其他优秀产品对比如下:

SOAR sqlcheck pt-query-advisor SQL Advisor Inception sqlautoreview
启发式建议 ✔️ ✔️ ✔️ ✔️ ✔️
索引建议 ✔️ ✔️ ✔️
查询重写 ✔️
执行计划展示 ✔️
Profiling ✔️
Trace ✔️
SQL在线执行 ✔️
数据备份 ✔️

从上图可以看出,支持的功能丰富,其功能特点如下:

  • 跨平台支持(支持 Linux, Mac 环境,Windows 环境理论上也支持,不过未全面测试)
  • 目前只支持 MySQL 语法族协议的 SQL 优化
  • 支持基于启发式算法的语句优化
  • 支持复杂查询的多列索引优化(UPDATE, INSERT, DELETE, SELECT)
  • 支持 EXPLAIN 信息丰富解读
  • 支持 SQL 指纹、压缩和美化
  • 支持同一张表多条 ALTER 请求合并
  • 支持自定义规则的 SQL 改写

就介绍这么多吧,既然是SQL优化工具,光说是没有用的,我们还是先用起来看看效果吧。

安装

这里有两种安装方式,如下:

下载二进制安装包

$ wget https://github.com/XiaoMi/soar/releases/download/0.11.0/soar.linux-amd64 -O soar
chmod a+x soar

这里建议直接下载最新版,要不会有bug。

下载好的二进制文件添加到环境变量中即可(不会的谷歌一下吧,这里就不讲了)。

测试一下:

$ echo 'select * from user' | soar.darwin-amd64(根据你自己的二进制文件名来输入)
# Query: AC4262B5AF150CB5

★ ★ ★ ☆ ☆ 75分

```sql
SELECT
 *
FROM
 USER
```

## 最外层 SELECT 未指定 WHERE 条件

* **Item:** CLA.001

* **Severity:** L4

* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。

## 不建议使用 SELECT * 类型查询

* **Item:** COL.001

* **Severity:** L1

* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。

源码安装

依赖环境:

1. Go 1.10+
2. git

高级依赖(仅面向开发人员)

  • mysql 客户端版本需要与容器中MySQL版本相同,避免出现由于认证原因导致无法连接问题
  • docker MySQL Server测试容器管理
  • govendor Go包管理
  • retool 依赖外部代码质量静态检查工具二进制文件管理

生成二进制文件:

go get -d github.com/XiaoMi/soar
cd ${GOPATH}/src/github.com/XiaoMi/soar && make
生成的二进制文件与上面一样,直接放入环境变量即可,这里我没有尝试,靠你们自己踩坑了呦~~~

简单使用

0. 前置准备

准备一个table,如下:

CREATE TABLE `users` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `username` varchar(64) NOT NULL DEFAULT '',
 `nickname` varchar(255) DEFAULT '',
 `password` varchar(256) NOT NULL DEFAULT '',
 `salt` varchar(48) NOT NULL DEFAULT '',
 `avatar` varchar(128) DEFAULT NULL,
 `uptime` datetime DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4

1. 直接输入sql语句(不运行)

$ echo "select * from users" | soar.darwin-amd64
$ # Query: 30AFCB1E1344BEBD

★ ★ ★ ☆ ☆ 75分

```sql
SELECT
 *
FROM
 users
```
## 最外层 SELECT 未指定 WHERE 条件

* **Item:** CLA.001

* **Severity:** L4

* **Content:** SELECT 语句没有 WHERE 子句,可能检查比预期更多的行(全表扫描)。对于 SELECT COUNT(\*) 类型的请求如果不要求精度,建议使用 SHOW TABLE STATUS 或 EXPLAIN 替代。

## 不建议使用 SELECT * 类型查询

* **Item:** COL.001

* **Severity:** L1

* **Content:** 当表结构变更时,使用 \* 通配符选择所有列将导致查询的含义和行为会发生更改,可能导致查询返回更多的数据。

现在是完全根据SQL语句进行分析的,因为没有连接到mysql。可以看到,给出的报告也很详细,但是只是空壳子,仅凭SQL语句给出的分析并不是准确的,所以我们开始接下来的应用。

2. 连接mysql生成EXPLAIN分析报告

我们可以在配置文件中配置好mysql相关的配置,操作如下:

vi soar.yaml
# yaml format config file
online-dsn:
  addr:   127.0.0.1:3306
  schema:  asong
  user:   root
  password: root1997
  disable: false

test-dsn:
  addr:   127.0.0.1:3306
  schema:  asong
  user:   root
  password: root1997
  disable: false

配置好了,我们来实践一下子吧:

$ echo "SELECT id,username,nickname,password,salt,avatar,uptime FROM users WHERE username = 'asong1111'" | soar.darwin-amd64 -test-dsn="root:root1997@127.0.0.1:3306/asong" -allow-online-as-test -log-output=soar.log
$ # Query: D12A420193AD1674

★ ★ ★ ★ ★ 100分

```sql
SELECT
 id, username, nickname, PASSWORD, salt, avatar, uptime
FROM
 users
WHERE
 username = 'asong1111'
```

## Explain信息

| id | select\_type | table | partitions | type | possible_keys | key | key\_len | ref | rows | filtered | scalability | Extra |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | *users* | NULL | const | username | username | 258 | const | 1 | ☠️ **100.00%** | ☠️ **O(n)** | NULL |

### Explain信息解读

#### SelectType信息解读

* **SIMPLE**: 简单SELECT(不使用UNION或子查询等).

#### Type信息解读

* **const**: const用于使用常数值比较PRIMARY KEY时, 当查询的表仅有一行时, 使用system. 例:SELECT * FROM tbl WHERE col = 1.

这回结果中多了EXPLAIN信息分析报告。这对于刚开始入门的小伙伴们是友好的,因为我们对Explain解析的字段并不熟悉,有了它我们可以完美的分析SQL中的问题,是不是很棒。

3. 语法检查

soar工具不仅仅可以进行sql语句分析,还可以进行对sql语法进行检查,找出其中的问题,来看个例子:

$ echo "selec * from users" | soar.darwin-amd64 -only-syntax-check
At SQL 1 : line 1 column 5 near "selec * from users" (total length 18)

这里select关键字少了一个t,运行该指令帮助我们一下就定位了问题,当我们的sql语句很长时,就可以使用该指令来辅助我们检查SQL语句是否正确。

4. SQL美化

我们日常开发时,经常会看其他人写的代码,因为水平不一样,所以有些SQL语句会写的很乱,所以这个工具就派上用场了,我们可以把我们的SQL语句变得漂亮一些,更容易我们理解哦。

$ echo "SELECT id,username,nickname,password,salt,avatar,uptime FROM users WHERE username = 'asong1111'" | soar.darwin-amd64 -report-type=pretty

SELECT
 id, username, nickname, PASSWORD, salt, avatar, uptime
FROM
 users
WHERE
 username = 'asong1111';

这样看起来是不是更直观了呢~~。

结尾

因为我也才是刚使用这个工具,更多的玩法我还没有发现,以后补充。更多玩法可以自己研究一下,github传送门:https://github.com/XiaoMi/soar。官方文档其实很粗糙,更多方法解锁还要靠自己研究,毕竟源码已经给我们了,对于学习go也有一定帮助,当作一个小项目慢慢优化岂不是更好呢~~。

到此这篇关于Mysql优化神器(推荐)的文章就介绍到这了,更多相关Mysql优化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MYSQL性能优化分享(分库分表)

    1.分库分表 很明显,一个主表(也就是很重要的表,例如用户表)无限制的增长势必严重影响性能,分库与分表是一个很不错的解决途径,也就是性能优化途径,现在的案例是我们有一个1000多万条记录的用户表members,查询起来非常之慢,同事的做法是将其散列到100个表中,分别从members0到members99,然后根据mid分发记录到这些表中,牛逼的代码大概是这样子: 复制代码 代码如下: <?php for($i=0;$i< 100; $i++ ){ //echo "CREATE TA

  • MySQL 性能优化的最佳20多条经验分享

    当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这些优化技巧对你有用. 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的.当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中,这样,后续的相同的查询就不用操作表而直接访问缓存结果了. 这里最主要

  • MySQL性能优化之max_connections配置参数浅析

    MySQL的max_connections参数用来设置最大连接(用户)数.每个连接MySQL的用户均算作一个连接,max_connections的默认值为100.本文将讲解此参数的详细作用与性能影响. 与max_connections有关的特性 MySQL无论如何都会保留一个用于管理员(SUPER)登陆的连接,用于管理员连接数据库进行维护操作,即使当前连接数已经达到了max_connections.因此MySQL的实际最大可连接数为max_connections+1: 这个参数实际起作用的最大值

  • Mysql查询最近一条记录的sql语句(优化篇)

    下策--查询出结果后将时间排序后取第一条 select * from a where create_time<="2017-03-29 19:30:36" order by create_time desc limit 1 这样做虽然可以取出当前时间最近的一条记录,但是一次查询需要将表遍历一遍,对于百万以上数据查询将比较费时:limit是先取出全部结果,然后取第一条,相当于查询中占用了不必要的时间和空间:还有如果需要批量取出最近一条记录,比方说:"一个订单表,有用户,订

  • 优化Mysql数据库的8个方法

    1.创建索引对于查询占主要的应用来说,索引显得尤为重要.很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或者说没有添加更为有效的索引导致.如果不加索引的话,那么查找任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下降.但是也不是什么情况都非得建索引不可,比如性别可能就只有两个值,建索引不仅没什么优势,还会影响到更新速度,这被称为过度索引.2.复合索引比如有一条语句是这样的:select * from users

  • MySQL优化必须调整的10项配置

    当我们被人雇来监测MySQL性能时,人们希望我们能够检视一下MySQL配置然后给出一些提高建议.许多人在事后都非常惊讶,因为我们建议他们仅仅改动几个设置,即使是这里有好几百个配置项.这篇文章的目的在于给你一份非常重要的配置项清单. 我们曾在几年前在博客里给出了这样的建议,但是MySQL的世界变化实在太快了!写在开始前-即使是经验老道的人也会犯错,会引起很多麻烦.所以在盲目的运用这些推荐之前,请记住下面的内容: 一次只改变一个设置!这是测试改变是否有益的唯一方法. 大多数配置能在运行时使用SET

  • MYSQL 优化常用方法

    1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小.例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了.同样的,如果可以的话,我们应该使用MEDIUMINT而不是 BIGIN来定义整型字段. 另外一个提高效率的方法

  • MySQL Order by 语句用法与优化详解

    MySQL Order By keyword是用来给记录中的数据进行分类的.MySQL Order By Keyword根据关键词分类ORDER BY keyword是用来给记录中的数据进行分类的. 复制代码 代码如下: SELECT column_name(s) FROM table_name ORDER BY column_name 例子 SQL创建代码: 复制代码 代码如下: CREATE TABLE IF NOT EXISTS mysql_order_by_test (  uid int

  • Mysql优化神器(推荐)

    前言 今天逛github时,发现了这款对 SQL 进行优化和改写的自动化工具sora.感觉挺不错的,就下载学习了一下.这个工具支持的功能比较多,可以作为我们日常开发中的一款辅助工具,现在我就把它推荐给你们--- github传送门:https://github.com/XiaoMi/soar 背景 在我们日常开发中,优化SQL总是我们日常开发任务之一.例行 SQL 优化,不仅可以提升程序性能,还能够降低线上故障的概率. 目前常用的 SQL 优化方式包括但不限于:业务层优化.SQL逻辑优化.索引优

  • MySQL提升大量数据查询效率的优化神器

    目录 前言 查看SQL执行频率 定位低效率执行SQL explain分析执行计划 trace分析优化器执行计划 使用索引优化 SQL优化 大量插入数据 优化insert语句 优化order by语句 2.两种排序方式 3.Filesort 的优化 优化group by 子查询优化 limit优化 前言 在应用的的开发过程中,由于初期数据量小,开发人员写 SQL 语句时更重视功能上的实现,但是当应用系统正式上线后,随着生产数据量的急剧增长,很多 SQL 语句开始逐渐显露出性能问题,对生产的影响也越

  • Mysql优化策略(推荐)

    总的来说: 1.数据库设计和表创建时就要考虑性能 2.sql的编写需要注意优化 3.分区.分表.分库 设计表的时候: 1.字段避免null值出现,null值很难查询优化且占用额外的索引空间,推荐默认数字0代替null. 2.尽量使用INT而非BIGINT,如果非负则加上UNSIGNED(这样数值容量会扩大一倍),当然能使用TINYINT.SMALLINT.MEDIUM_INT更好. 3.使用枚举或整数代替字符串类型 4.尽量使用TIMESTAMP而非DATETIME 5.单表不要有太多字段,建议

  • MySQL优化常用的19种有效方法(推荐!)

    目录 1.EXPLAIN 2.SQL语句中IN包含的值不应过多 3.SELECT语句务必指明字段名称 4.当只需要一条数据的时候,使用limit1 5.如果排序字段没有用到索引,就尽量少排序 6.如果限制条件中其他字段没有索引,尽量少用or 7.尽量用unionall代替union 8.不使用ORDERBYRAND() 9.区分in和exists.notin和notexists 10.使用合理的分页方式以提高分页的效率 11.分段查询 12.避免在where子句中对字段进行null值判断 13.

  • mysql 优化日记

    同时在线访问量继续增大 对于1G内存的服务器明显感觉到吃力严重时甚至每天都会死机 或者时不时的服务器卡一下 这个问题曾经困扰了我半个多月MySQL使用是很具伸缩性的算法,因此你通常能用很少的内存运行或给MySQL更多的被存以得到更好的性能. 安装好mysql后,配制文件应该在/usr/local/mysql/share/mysql目录中,配制文件有几个,有my-huge.cnf my-medium.cnf my-large.cnf my-small.cnf,不同的流量的网站和不同配制的服务器环境

  • MySQL优化配置文件my.ini(discuz论坛)

    在Apache, PHP, MySQL的体系架构中,MySQL对于性能的影响最大,也是关键的核心部分.对于Discuz!论坛程序也是如此,MySQL的设置是否合理优化,直接影响到论坛的速度和承载量!同时,MySQL也是优化难度最大的一个部分,不但需要理解一些MySQL专业知识,同时还需要长时间的观察统计并且根据经验进行判断,然后设置合理的参数. 下面我们了解一下MySQL优化的一些基础,MySQL的优化我分为两个部分,一是服务器物理硬件的优化,二是MySQL自身(my.cnf)的优化. 一.服务

  • Linux中对MySQL优化实例详解

    Linux中对MySQL优化实例详解 vim /etc/my.cnf以下只列出my.cnf文件中[mysqld]段落中的内容,其他段落内容对MySQL运行性能影响甚微,因而姑且忽略. [mysqld] port = 3306 serverid = 1 socket = /tmp/mysql.sock skip-locking 避免MySQL的外部锁定,减少出错几率增强稳定性. skip-name-resolve 禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析

  • LAMP服务器性能优化技巧之Mysql优化

    Apache服务器优化.PHP优化.Mysql优化 对于程序开发人员而言,目前使用最流行的两种后台数据库即为MySQL and SQL Server.这两者最基本的相似之处在于数据存储和属于查询系统.如果你想建立一个.NET服务器体系,这一体系可以从多个不同平台访问数据,参与数据库的管理,那么你可以选用SQL Server服务器.如果你想建立一个第三方动态网站,从这一站点可以从一些客户端读取数据,那么MySQL将是一个不错的选择. 1.编译和安装MySQL 通过你的系统挑选可能最好的编译器,你通

  • 数据库管理中19个MySQL优化方法

    MySQL数据库优化以后,不仅可以减少数据库的冗余,而且还可以让数据库运行速度都有所改变,下面使我们整理的19条非常好的MySQL数据库优化方法,参考一下. 声明一下:下面的优化方案都是基于 " Mysql-索引-BTree类型 " 的 一.EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划. 下面来个简单的示例,标注(1,2,3,4,5)我们要重点关注的数据 type列,连接类型.一个好的sql语句至少要达到range级别.杜绝出现all级别 key列,

  • MySQL优化SQL语句的技巧

    在面对不够优化.或者性能极差的SQL语句时,我们通常的想法是将重构这个SQL语句,让其查询的结果集和原来保持一样,并且希望SQL性能得以提升.而在重构SQL时,一般都有一定方法技巧可供参考,本文将介绍如何通过这些技巧方法来重构SQL. 一.分解SQL 有时候对于一个复杂SQL,我们首先想到的是是否需要将一个复杂SQL分解成多个简单SQL,来完成相同业务处理结果. 在以前,大家总是强调需要数据库层来完成尽可能的工作,这也就不难理解在一些老的产品.项目中时常会看见很多超级复杂.超级长的SQL语句,这

随机推荐