循序渐进丨AI时代,MogDB 数据库如何应对慢SQL?

众所周知,openGauss 在AI4DB方面有不少创新,MogDB 完全继承了 openGauss 在AI4DB方面的能力并进一步做了增强。在 MogDB 3.1版本中,AI4DB方面引入了一个非常重要的组件DBmind,其中包含一个SQL改写工具,即SQL Rewriter。我相信对于很多DBA来讲,这一定是很大的福音,以后再也不必为应用的慢SQL发愁了。

DBmind的基本原理是根据预先设定的规则(已内置到SQL引擎),将查询语句转换为更为高效或更为规范的形式,使得查询效率得以提升。这里我就为大家简单演示一下其具体的用法。

首先准备一下环境

MogDB 3.1环境缺少constant文件,因此需要先安装一些Python依赖包:

cat >> $GAUSSHOME/bin/constant <<EOF
 MIN_PYTHON_VERSION="(3,6)"
MAX_PYTHON_VERSION="(3,9)"
EOF

可以通过查看 $GAUSSHOME/bin/dbmind/requirements-aarch64.txt 来确认具体的环境要求。我们先配置好PIP环境:

mkdir -p ~/.pip
cat > ~/.pip/pip.conf <<EOF
[global]

index-url = https://repo.huaweicloud.com/repository/pypi/simple

[install]

trusted-host = https://repo.huaweicloud.com

准备就绪之后,就可以开始安装Python依赖包了:

python3 -m pip  install --upgrade pip --user

python3 -m pip install -r $GAUSSHOME/bin/dbmind/requirements-aarch64.txt  --trusted-host repo.huaweicloud.com -i http://repo.huaweicloud.com/repository/pypi/simple --user

 python3 -m pip  install psycopg2 --user
如果报错,换成
 python3 -m pip  install psycopg2-binary --user

万事俱备,只欠东风!接下来我们就测一测DBmind的能力。

先来了解一下这个强大的AI工具的基本用法:

gs_dbmind component sql_rewriter [PORT] [DBNAME] [SQLFILE] --db-host [default socketfile] --db-user [default init user] --schema [default public]

当然对于其支持的自动改写规则,也并非是全部都支持,目前暂时支持如下的一些rule:

class Delete2Truncate(Rule):
class Star2Columns(Rule):
class Having2Where(Rule):
class AlwaysTrue(Rule):
class DistinctStar(Rule):
class UnionAll(Rule):
class OrderbyConst(Rule):
class Or2In(Rule):
class OrderbyConstColumns(Rule):
class ImplicitConversion(Rule):
class SelfJoin(Rule):

这里我们事先准备好一些相对简单的测试用例,内容如下:

cat > rewrite_example.sql <<EOF
delete /* 无条件的delete转换成truncate */ 
from test1;
select /* 星号替换成具体列名 */ * 
from test1;
select /*Union替换成 Union All*/id,name 
from test1
union 
select id,name 
from test2;
select /*order by 列号替换成具体列名 */id,name 
from test1 order by 1;
select /*返回单行的去掉order by */ id 
from test1 where id=1 order by id;
select /*Or 改为 in */id,name 
from test1 where id = 0 or id = 1;
select /* Having 列不属于聚合函数的改成Where */ id,count(*) 
from test1 group by id having id > 0 ;
select /*去掉恒为True的表达式*/id,name 
from test1 where 1=1;
select  /*预计算转换*/ id,name 
from test1 where id + 1 < 2 ;
select /*自连接非等式连接改为等式连接*/ a.id,b.name 
from test1 a , test1 b
 where a.id - b.id <= 20 and a.id > b.id;
select /*distinct 带主键去掉distinct */  distinct * 
from test1;
EOF

测试脚本准备完毕之后,我们就可以使用DBmind来验证一下其改写能力了。具体的执行命令如下:

gs_dbmind component sql_rewriter $PGPORT postgres rewrite_example.sql --db-user tpcc  --db-host 127.0.0.1

最后我们来看看DBmind执行的结果是否如想象的那般神奇:

+-------------------------------------------------------+----------------------------------------------------+
| Raw SQL                                               | Rewritten SQL                                      |
+-------------------------------------------------------+----------------------------------------------------+
| delete                                                | TRUNCATE TABLE test1;                              |
| /* 无条件的delete转换成truncate */                      |                                                    |
| from test1;                                           |                                                    |
| select                                                | SELECT id,                                         |
| /* 星号替换成具体列名 */ *                               |        name                                        |
| from test1;                                           | FROM test1;                                        |
| select                                                | SELECT id,                                         |
| /*Union替换成 Union All*/id,name                       |        name                                        |
| from test1                                            | FROM test1                                         |
| union                                                 | UNION ALL                                          |
| select id,name                                        | SELECT id,                                         |
| from test2;                                           |        name                                        |
|                                                       | FROM test2;                                        |
| select                                                | SELECT id,                                         |
|  /*order by 列号替换成具体列名 */id,name                 |        name                                        |
| from test1 order by 1;                                | FROM test1                                         |
|                                                       | ORDER BY id;                                       |
| select                                                | SELECT id                                          |
|  /*返回单行的去掉order by */ id                         | FROM test1                                         |
| from test1 where id=1 order by id;                    | WHERE id = 1;                                      |
| select                                                | SELECT id,                                         |
|  /*Or 改为 in */id,name                               |        name                                        |
| from test1 where id = 0 or id = 1;                    | FROM test1                                         |
|                                                       | WHERE id IN (0,                                    |
|                                                       |              1);                                   |
| select                                                | SELECT id,                                         |
| /* Having 列不属于聚合函数的改成Where */ id,count(*)     |        COUNT(*)                                    |
| from test1 group by id having id > 0 ;                | FROM test1                                         |
|                                                       | WHERE id > 0                                       |
|                                                       | GROUP BY id;                                       |
| select                                                | SELECT id,                                         |
| /*去掉恒为True的表达式*/id,name                         |        name                                        |
| from test1 where 1=1;                                 | FROM test1;                                        |
| select                                                | SELECT id,                                         |
| /*预计算转换*/ id,name                                 |        name                                        |
| from test1 where id + 1 < 2 ;                         | FROM test1                                         |
|                                                       | WHERE id < 1;                                      |
| select                                                | SELECT *                                           |
| /*自连接非等式连接改为等式连接*/ a.id,b.name              | FROM                                               |
| from test1 a , test1 b                                |   (SELECT a.id,                                    |
|  where a.id - b.id <= 20 and a.id > b.id;             |           b.name                                   |
|                                                       |    FROM test1 AS a,                                |
|                                                       |         test1 AS b                                 |
|                                                       |    WHERE TRUNC((a.id) / 20) = TRUNC(b.id / 20)     |
|                                                       |      AND a.id > b.id                               |
|                                                       |    UNION ALL SELECT a.id,                          |
|                                                       |                     b.name                         |
|                                                       |    FROM test1 AS a,                                |
|                                                       |         test1 AS b                                 |
|                                                       |    WHERE TRUNC((a.id) / 20) = TRUNC(b.id / 20 + 1) |
|                                                       |      AND a.id - b.id <= 20);                       |
| select                                                | SELECT id,                                         |
| /*distinct * 带主键去掉distinct */  distinct *         |        name                                        |
| from test1;                                           | FROM test1;                                        |
+-------------------------------------------------------+----------------------------------------------------+

我们可以看到DBmind完美地改写了11个SQL。怎么样?是不是很Cool~~~~

关于作者

罗海雄,云和恩墨数据库研发架构师,性能优化专家,2012年 ITPUB 全国SQL大赛冠军。他拥有超十年企业级系统设计与优化经验,对SQL优化理解尤其深入,曾服务于甲骨文公司。

a1ef6110ad0a9ce4534bc4ff3d42eb8e.gif

数据驱动,成就未来,云和恩墨,不负所托!


云和恩墨创立于2011年,是业界领先的“智能的数据技术提供商”。公司总部位于北京,在国内外35个地区设有本地办公室并开展业务。

云和恩墨以“数据驱动,成就未来”为使命,致力于将创新的数据技术产品和解决方案带给全球的企业和组织,帮助客户构建安全、高效、敏捷且经济的数据环境,持续增强客户在数据洞察和决策上的竞争优势,实现数据驱动的业务创新和升级发展。

自成立以来,云和恩墨专注于数据技术领域,根据不断变化的市场需求,创新研发了系列软件产品,涵盖数据库、数据库存储、数据库云管和数据智能分析等领域。这些产品已经在集团型、大中型、高成长型客户以及行业云场景中得到广泛应用,证明了我们的技术和商业竞争力,展现了公司在数据技术端到端解决方案方面的优势。

在云化、数字化和智能化的时代背景下,云和恩墨始终以正和多赢为目标,感恩每一位客户和合作伙伴的信任与支持,“利他先行”,坚持投入于数据技术核心能力,为构建数据驱动的智能未来而不懈努力。

我们期待与您携手,共同探索数据力量,迎接智能未来。

3bec21cc78d866f8f23e638c631b86e2.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值