OceanBase中NOT EXISTS是否需要被改写

作者简介

张瑞远,曾经从事银行、证券数仓设计、开发、优化类工作,现主要从事电信级IT系统及数据库的规划设计、架构设计、运维实施、运维服务、故障处理、性能优化等工作。 持有Orale OCM,MySQL OCP及国产代表数据库认证。 获得的专业技能与认证包括 OceanBase OBCE、Oracle OCP 11g、OracleOCM 11g 、MySQL OCP 5.7 、腾讯云TBase、腾讯云TDSQ

背景:

前段时间写了一篇《 关于OB中左外连接和反连接的探究 》的文章。OceanBase官网知识库后来也更新了这部分的内容,链接如下:

https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000475695 

1704244993

这意味着在OceanBase中就不建议使用not exists,或者说只能通过改写来优化它吗?

实际上,并非如此。包括我在文章中的介绍,也仅仅是表明在特定情况下,batch rescan的优化性能可能会优于无法使用该特性的anti join,但这并不意味着not exists的优化途径仅此一种。

为了更直观地说明这一点,我仍倾向于通过实验来验证。

接下来,我将以我之前文章中的sql为例,进行一次优化实验。

实验过程:

sql原文及效率和执行计划如下,因为CTM_GM是视图,所以执行计划中看到的表名是SD_CTM_GM。

#####sql文本
 select  count(1)
    from tttt.mmmmm_sssssale t
   where t.sssss  not in ('e111', 'ddddda')
     and t.stats  = '1'
     and t.parean  is null
     and t.city  = 2208
     AND (t.cusystatus  = 'FFFFGGGGG')
     AND (T.ORGGGGGGNEL  is null or T.ORGGGGGGNEL  != 'infonow')
      AND NOT EXISTS (SELECT  1
            FROM tttt.TTTT_OWN_C  TOW
           WHERE T.PID  = TOW.OID
             AND TOW.CT_ID  = T.city 
             AND TOW.OODDD_sTS   IN
                 (SELECT DDDC
                    FROM tttt.CTM_GM
                   WHERE GPID  = 'OtherThing '
       AND stats  = '1'))  and to_char(createdate,'yyyymmdd') between 20150101 and 202301211;	
###执行时间
 +----------+
| COUNT(1) |
+----------+
|    29493 |
+----------+
1 row in set (43.87 sec)
####执行计划
| ===========================================================================================
|ID|OPERATOR                           |NAME                             |EST. ROWS|COST  |
-------------------------------------------------------------------------------------------
|0 |SCALAR GROUP BY                    |                                 |1        |161064|
|1 | NESTED-LOOP ANTI JOIN             |                                 |808      |161033|
|2 |  TABLE SCAN                       |T                                |1278     |40623 |
|3 |  PX COORDINATOR                   |                                 |1        |94    |
|4 |   EXCHANGE OUT DISTR              |:EX10001                         |1        |94    |
|5 |    SUBPLAN SCAN                   |VIEW2                            |1        |94    |
|6 |     NESTED-LOOP JOIN              |                                 |1        |94    |
|7 |      EXCHANGE IN DISTR            |                                 |1        |92    |
|8 |       EXCHANGE OUT DISTR (BC2HOST)|:EX10000                         |1        |92    |
|9 |        TABLE SCAN                 |TOW(IDX_TTTT_OWN_C _ORDERID)     |1        |92    |
|10|      TABLE SCAN                   |SD_CTM_GM(PK_SD_CTM_GM)          |1        |32    | 
===========================================================================================

Outputs & filters: 
-------------------------------------
  0 - output([T_FUN_COUNT(*)]), filter(nil), 
      group(nil), agg_func([T_FUN_COUNT(*)])
  1 - output([1]), filter(nil), 
      conds(nil), nl_params_([T.PID ])
  2 - output([T.PID ]), filter([T.city  = 2208], [cast(cast(TO_CHAR(T.CREATEDATE, ?), VARCHAR2(256 BYTE)), NUMBER(-1, -85)) >= 20150101], [cast(cast(TO_CHAR(T.CREATEDATE, ?), VARCHAR2(256 BYTE)), NUMBER(-1, -85)) <= 202301211], [(T_OP_IS, T.ORGGGGGGNEL , NULL, 0) OR T.ORGGGGGGNEL  != ?], [(T_OP_NOT_IN, T.sssss , (?, ?))], [(T_OP_IS, T.parean , NULL, 0)], [T.stats  = ?], [T.cusystatus  = ?]), 
      access([T.sssss ], [T.stats ], [T.parean ], [T.city ], [T.cusystatus ], [T.ORGGGGGGNEL ], [T.PID ], [T.CREATEDATE]), partitions(p0)
  3 - output([1]), filter(nil)
  4 - output([1]), filter(nil), is_single, dop=1
  5 - output([1]), filter(nil), 
      access([VIEW2.TOW.OID])
  6 - output([TOW.OID]), filter(nil), 
      conds(nil), nl_params_([TOW.OODDD_sTS  ])
  7 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter(nil)
  8 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter(nil), is_single, dop=1
  9 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter([TOW.CT_ID  = 2208]), 
      access([TOW.OID], [TOW.CT_ID ], [TOW.OODDD_sTS  ]), partitions(p0)
  10 - output([1]), filter([SD_CTM_GM.stats  = ?]), 
      access([SD_CTM_GM.stats ]), partitions(p0)

可以看到该sql走了NESTED-LOOP ANTI JOIN,执行时间是43s,执行时间比较长。

按照正常的优化思路来分析下,咱们先看下实际的数据量。

obclient>  select  count(1)
    ->     from tttt.mmmmm_sssssale t
    ->    where t.sssss  not in ('e111', 'ddddda')
    ->      and t.stats  = '1'
    ->      and t.parean  is null
    ->      and t.city  = 2208
    ->      AND (t.cusystatus  = 'FFFFGGGGG')
    ->      AND (T.ORGGGGGGNEL  is null or T.ORGGGGGGNEL  != 'infonow') and to_char(createdate,'yyyymmdd') between 20150101 and 202301211; 
+----------+
| COUNT(1) |
+----------+
|    29493 |
+----------+
1 row in set (0.08 sec)

obclient> SELECT count(*)
    ->                     FROM tttt.CTM_GM
    ->                    WHERE GPID  = 'OtherThing '
    ->        AND stats  = '1' ;
+----------+
| COUNT(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

obclient> SELECT count(*) from  tttt.TTTT_OWN_C  TOW;
+----------+
| COUNT(*) |
+----------+
|  5087140 |
+----------+
1 row in set (1.99 sec)

可以看到CTM_GM的结果是0行,扫描速度很快,那么not exists的子查询结果也是0行,但是TOW表有500W数据,原本的执行计划是TOW通过nl连接CTM_GM,要取TOW的结果集去匹配CTM_GM,理论上我们修改这两个表关联顺序,就可以只取CTM_GM的0行消除掉TOW表这么大数据量的消耗代价。


######sql文本
select /*+use_nl(@"SEL$1" ("VIEW2"@"SEL$1" ))*/ count(1)
    from tttt.mmmmm_sssssale t
   where t.sssss  not in ('e111', 'ddddda')
     and t.stats  = '1'
     and t.parean  is null
     and t.city  = 2208
     AND (t.cusystatus  = 'FFFFGGGGG')
     AND (T.ORGGGGGGNEL  is null or T.ORGGGGGGNEL  != 'infonow')
      AND NOT EXISTS (SELECT  /*+leading(CTM_GM) use_nl(CTM_GM,TOW) */ 1
            FROM tttt.TTTT_OWN_C  TOW
           WHERE T.PID  = TOW.OID
             AND TOW.CT_ID  = T.city 
             AND TOW.OODDD_sTS   IN
                 (SELECT DDDC
                    FROM tttt.CTM_GM
                   WHERE GPID  = 'OtherThing '
       AND stats  = '1'))  and to_char(createdate,'yyyymmdd') between 20150101 and 202301211;		

#######执行效率
+----------+
| COUNT(1) |
+----------+
|    29493 |
+----------+
1 row in set (0.21 sec)	  


####执行计划

| =========================================================================================
|ID|OPERATOR                |NAME                                      |EST. ROWS|COST  |
-----------------------------------------------------------------------------------------
|0 |SCALAR GROUP BY         |                                          |1        |275986|
|1 | NESTED-LOOP ANTI JOIN  |                                          |808      |275955|
|2 |  PX COORDINATOR        |                                          |1278     |41514 |
|3 |   EXCHANGE OUT DISTR   |:EX10000                                  |1278     |40623 |
|4 |    TABLE SCAN          |T                                         |1278     |40623 |
|5 |  SUBPLAN SCAN          |VIEW2                                     |1        |183   |
|6 |   NESTED-LOOP JOIN     |                                          |1        |183   |
|7 |    TABLE SCAN          |SD_CTM_GM(INX_SD_CTM_GM_GPID )|1        |92    |
|8 |    MATERIAL            |                                          |1        |92    |
|9 |     PX COORDINATOR     |                                          |1        |92    |
|10|      EXCHANGE OUT DISTR|:EX20000                                  |1        |92    |
|11|       TABLE SCAN       |TOW(IDX_TTTT_OWN_C _ORDERID)            |1        |92    |
=========================================================================================

Outputs & filters: 
-------------------------------------
  0 - output([T_FUN_COUNT(*)]), filter(nil), 
      group(nil), agg_func([T_FUN_COUNT(*)])
  1 - output([1]), filter(nil), 
      conds(nil), nl_params_([T.PID ])
  2 - output([T.PID ]), filter(nil)
  3 - output([T.PID ]), filter(nil), is_single, dop=1
  4 - output([T.PID ]), filter([T.city  = 2208], [cast(cast(TO_CHAR(T.CREATEDATE, ?), VARCHAR2(256 BYTE)), NUMBER(-1, -85)) >= 20150101], [cast(cast(TO_CHAR(T.CREATEDATE, ?), VARCHAR2(256 BYTE)), NUMBER(-1, -85)) <= 202301211], [(T_OP_IS, T.ORGGGGGGNEL , NULL, 0) OR T.ORGGGGGGNEL  != ?], [(T_OP_NOT_IN, T.sssss , (?, ?))], [(T_OP_IS, T.parean , NULL, 0)], [T.stats  = ?], [T.cusystatus  = ?]), 
      access([T.sssss ], [T.stats ], [T.parean ], [T.city ], [T.cusystatus ], [T.ORGGGGGGNEL ], [T.PID ], [T.CREATEDATE]), partitions(p0)
  5 - output([1]), filter(nil), 
      access([VIEW2.TOW.OID])
  6 - output([TOW.OID]), filter(nil), 
      conds([TOW.OODDD_sTS   = SD_CTM_GM.DDDC]), nl_params_(nil)
  7 - output([SD_CTM_GM.DDDC]), filter([SD_CTM_GM.stats  = ?]), 
      access([SD_CTM_GM.stats ], [SD_CTM_GM.DDDC]), partitions(p0)
  8 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter(nil)
  9 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter(nil)
  10 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter(nil), is_single, dop=1
  11 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter([TOW.CT_ID  = 2208]), 
      access([TOW.OID], [TOW.CT_ID ], [TOW.OODDD_sTS  ]), partitions(p0) 

通过添加hint的方式我们可以看到我只调整了TOW和CTM_GM的连接顺序,效率从43s优化到了0.21s,而我上一篇文章中改写之后的效率是1s,所以该sql不需要改写就可以优化掉。

那这个效率还可以优化吗,看起来还有优化空间,既然not exists的结果集是0,那我用上面同样的方式,干预下view结果集和T表的顺序,能不能得到更好的结果那?

####sql文本
select /*+leading(("VIEW2"@"SEL$1" ))*/ count(1)
    from tttt.mmmmm_sssssale t
   where t.sssss  not in ('e111', 'ddddda')
     and t.stats  = '1'
     and t.parean  is null
     and t.city  = 2208
     AND (t.cusystatus  = 'FFFFGGGGG')
     AND (T.ORGGGGGGNEL  is null or T.ORGGGGGGNEL  != 'infonow')
      AND NOT EXISTS (SELECT  /*+leading(CTM_GM) use_nl(CTM_GM,TOW) */ 1
            FROM tttt.TTTT_OWN_C  TOW
           WHERE T.PID  = TOW.OID
             AND TOW.CT_ID  = T.city 
             AND TOW.OODDD_sTS   IN
                 (SELECT DDDC
                    FROM tttt.CTM_GM
                   WHERE GPID  = 'OtherThing '
       AND stats  = '1'))  and to_char(createdate,'yyyymmdd') between 20150101 and 202301211;		  
####执行效率	   
+----------+
| COUNT(1) |
+----------+
|    29493 |
+----------+
1 row in set (0.08 sec)
#########执行计划	   
| ==========================================================================================
|ID|OPERATOR                |NAME                                      |EST. ROWS|COST   |
------------------------------------------------------------------------------------------
|0 |SCALAR GROUP BY         |                                          |1        |2231317|
|1 | HASH RIGHT ANTI JOIN   |                                          |808      |2231286|
|2 |  SUBPLAN SCAN          |VIEW2                                     |470      |2188504|
|3 |   NESTED-LOOP JOIN     |                                          |470      |2188497|
|4 |    TABLE SCAN          |SD_CTM_GM(INX_SD_CTM_GM_GPID )|1        |92     |
|5 |    MATERIAL            |                                          |299244   |2182932|
|6 |     PX COORDINATOR     |                                          |299244   |2169701|
|7 |      EXCHANGE OUT DISTR|:EX10000                                  |299244   |2075029|
|8 |       TABLE SCAN       |TOW                                       |299244   |2075029|
|9 |  PX COORDINATOR        |                                          |1278     |41514  |
|10|   EXCHANGE OUT DISTR   |:EX20000                                  |1278     |40623  |
|11|    TABLE SCAN          |T                                         |1278     |40623  |
==========================================================================================

Outputs & filters: 
-------------------------------------
  0 - output([T_FUN_COUNT(*)]), filter(nil), 
      group(nil), agg_func([T_FUN_COUNT(*)])
  1 - output([1]), filter(nil), 
      equal_conds([T.PID  = VIEW2.TOW.OID]), other_conds(nil)
  2 - output([VIEW2.TOW.OID]), filter(nil), 
      access([VIEW2.TOW.OID])
  3 - output([TOW.OID]), filter(nil), 
      conds([TOW.OODDD_sTS   = SD_CTM_GM.DDDC]), nl_params_(nil)
  4 - output([SD_CTM_GM.DDDC]), filter([SD_CTM_GM.stats  = ?]), 
      access([SD_CTM_GM.stats ], [SD_CTM_GM.DDDC]), partitions(p0)
  5 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter(nil)
  6 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter(nil)
  7 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter(nil), is_single, dop=1
  8 - output([TOW.OID], [TOW.OODDD_sTS  ]), filter([TOW.CT_ID  = 2208]), 
      access([TOW.OID], [TOW.CT_ID ], [TOW.OODDD_sTS  ]), partitions(p0)
  9 - output([T.PID ]), filter(nil)
  10 - output([T.PID ]), filter(nil), is_single, dop=1
  11 - output([T.PID ]), filter([T.city  = 2208], [cast(cast(TO_CHAR(T.CREATEDATE, ?), VARCHAR2(256 BYTE)), NUMBER(-1, -85)) >= 20150101], [cast(cast(TO_CHAR(T.CREATEDATE, ?), VARCHAR2(256 BYTE)), NUMBER(-1, -85)) <= 202301211], [(T_OP_IS, T.ORGGGGGGNEL , NULL, 0) OR T.ORGGGGGGNEL  != ?], [(T_OP_NOT_IN, T.sssss , (?, ?))], [(T_OP_IS, T.parean , NULL, 0)], [T.stats  = ?], [T.cusystatus  = ?]), 
      access([T.sssss ], [T.stats ], [T.parean ], [T.city ], [T.cusystatus ], [T.ORGGGGGGNEL ], [T.PID ], [T.CREATEDATE]), partitions(p0)	   

可以看到现在效率0.08s比一开始的43s提升了500多倍比单纯的改写效率提升了12倍多,所以NOT EXISTS不一定需要改写,可能只是计划走错了,这种情况下我们绑定下计划就好了,很多时候应用改代码的代价也很大。

结论:

很多sql不是一定要去改写才能解决的,虽然改写有可能可以使用到一些优化算子,但是可能问题的根因不在这里,我们一定要提高自己分析问题的能力,准确判断分析问题,这样在工作中可以得心应手,也可以避免很多不必要的冗余的工作。

行之所向,莫问远方。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/494994.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 从0开始 工具操作解析【三】

同类博文; 安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 工具操作解析 安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 工具操作解析【二】-CSDN博客 回顾以往 在以前的博文简单介绍了这款工具的rom制作全程。今天针对这款工具的…

Rust 02.控制、引用、切片Slice

1.控制流 //rust通过所有权机制来管理内存&#xff0c;编译器在编译就会根据所有权规则对内存的使用进行 //堆和栈 //编译的时候数据的类型大小是固定的&#xff0c;就是分配在栈上的 //编译的时候数据类型大小不固定&#xff0c;就是分配堆上的 fn main() {let x: i32 1;{le…

YoloV5改进策略:Neck和Head改进|ECA-Net:用于深度卷积神经网络的高效通道注意力|多种改进方法|附结构图

摘要 本文使用ECA-Net注意力机制加入到YoloV5Neck和Head中。我尝试了多种改进方法&#xff0c;并附上改进结果&#xff0c;方便大家了解改进后的效果&#xff0c;为论文改进提供思路。&#xff08;改进中。。。。&#xff09; 论文&#xff1a;《ECA-Net&#xff1a;用于深度…

Android中运动事件的处理

1.目录 目录 1.目录 2.前言 3.程序演示 4.第二种程序示例 5.扩展 2.前言 触摸屏&#xff08;TouchScreen&#xff09;和滚动球&#xff08;TrackBall&#xff09;是 Android 中除了键盘之外的主要输入设备。如果需要使用触摸屏和滚动球&#xff0c;主要可以通过使用运动事…

ruoyi-nbcio-plus基于vue3的flowable的流程条件的升级修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

JavaScript中的继承方式详解

Question JavaScript实现继承的方式&#xff1f; 包含原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承和ES6 类继承 JavaScript实现继承的方式 在JavaScript中&#xff0c;实现继承的方式多种多样&#xff0c;每种方式都有其优势和适用场景。以下…

HarmonyOS(鸿蒙开发)入门篇

如果需要学习鸿蒙开发可以查看以下学习资源链接 OpenAtom OpenHarmony Develop applications - HUAWEI HarmonyOS APP 转载请注明出处HarmonyOS(鸿蒙开发&#xff09;入门篇-CSDN博客&#xff0c;谢谢&#xff01;

unity 数据的可视化

【Unity 实用插件篇】| 可视化图表插件XCharts (折线图、柱状图、饼图等)详细教学-腾讯云开发者社区-腾讯云 Package https://github.com/XCharts-Team/XCharts/releases 官方文档案例 入门教程&#xff1a;5分钟上手 XCharts 3.0 | XCharts (xcharts-team.github.io)

Linux 系统基础操作命令

当前市面上常见的系统&#xff1a;Windows、Linux、Mac OS、Android、IOS…… Linux 不太适合日常使用&#xff0c;但是非常适合用于开发。因此作为一个程序猿来说&#xff0c;Linux 都是务必要掌握的。 Linux 介绍 Linux 发行版 目前市面上比较知名的发行版有&#xff1a;R…

c(RGDfK)-FITC, 绿色荧光FITC标记细胞穿膜肽c(RGDfk

中文名称 &#xff1a;荧光标记c&#xff08;RGDfk&#xff09;环肽 英 文 名 &#xff1a;c(RGDfK)-FITC c(RGDfK(FITC)) 品 牌 &#xff1a;Tanshtech 单字母&#xff1a; c(RGD-DPhe-K&#xff08;Fitc&#xff09;) 三字母&#xff1a;Cyclo(Arg-Gly-Asp…

web学习笔记(四十六)

目录 1. path 路径模块 1.1 导入path模块 1.2 path.join()路径拼接 1.3 path.basename() 获取路径中的文件名 1.4 path.extname() 获取路径中的扩展名 2.服务器的相关概念 2.1 IP 地址 2.2 域名和域名服务器 2.3 端口号 3. http 模块 3.1使用http模块搭建服务器的步…

WIFI驱动移植实验:配置 Linux 内核

一. 简介 前面文章删除了Linux内核源码&#xff08;NXP官方的kernel内核源码&#xff09;自带的 WIFI驱动。 WIFI驱动移植实验&#xff1a;删除Linux内核自带的 RTL8192CU 驱动-CSDN博客 将正点原子提供的 rtl8188EUS驱动源码添加到 kernel内核源码中。文章如下&#xff1a…

Day59-Nginx反向代理与负载均衡算法精讲及会话保持精讲

Day59-Nginx反向代理与负载均衡算法精讲及会话保持精讲 7.nginx负载均衡调度算法7.1 什么是nginx负载均衡调度算法7.2 nginx负载均衡调度算法有哪些。 8.负载均衡后端的会话保持8.1 nginx负载均衡会话(session)保持8.2 负载均衡集群会话保持8.3 实践共享会话保持 7.nginx负载均…

《Mahjong Bump》

Mahjong Bump 类型&#xff1a;Tile 三消 视角&#xff1a;2d 乐趣点&#xff1a;清空杂乱快感&#xff0c;轻松的三合一休闲 平台&#xff1a;GP 时间&#xff1a;2021 个人职责&#xff1a; 所有程序部分开发 上架 GooglePlay 相关工做 针对游戏数据做出分析&#xff0c;讨论…

并发编程之的HashSet和HashMap的详细解析

HashSet不安全 HashSet也是线程不安全的&#xff0c;底层没有进行任何线程同步处理。 在hashset的源码中&#xff0c;底层是用hashmap实现的&#xff1a; 每次add的时候&#xff0c;把值放在了map对象中的key&#xff0c;而map对象的value则全部统一放一个常量&#xff1a; 在下…

【前端学习——js篇】6.事件模型

具体见&#xff1a;https://github.com/febobo/web-interview 6.事件模型 ①事件与事件流 事件(Events) 事件是指页面中发生的交互行为&#xff0c;比如用户点击按钮、键盘输入、鼠标移动等。在js中&#xff0c;可以通过事件来触发相应的操作&#xff0c;例如执行函数、改变…

STM32H743驱动SSD1309(3)

接前一篇文章&#xff1a;STM32H743驱动SSD1309&#xff08;2&#xff09; 三、命令说明 1. 设置命令锁定&#xff08;FDh&#xff09; 此双字节命令用于锁定OLED驱动器IC&#xff0c;不接受除其自身之外的任何命令。在输入FDh 16h&#xff08;A[2]&#xff1d;1b&#xff09;…

C语言文件操作详解

文件是什么 在我们日常使用的电脑上我们在电脑磁盘上会看到许许多多的文件夹&#xff0c;那里面的东西其实就是文件&#xff0c;为什么我们要使用文件&#xff1f;那是因为我们的电脑肯定会要用来存储东西的&#xff0c;如果没有文件&#xff0c;那么我们的东西都全部存放在内…

应急响应小结

应急响应的整体思路 应急响应的整体思路&#xff0c;就是上层有指导性原则和思想&#xff0c;下层有技能、知识点与工具&#xff0c;共同推进和保障应急响应流程的全生命周期。 原则和指导性思路 3W1H原则&#xff1a;3W即Who、What、Why&#xff0c;1H即How&#xff0c;做应…

Vastbase编程利器:PL/pgSQL原理简介

PL/pgSQL是Vastbase提供的一种过程语言&#xff0c;在普通SQL语句的使用上增加了编程语言的特点&#xff0c;可以用于创建函数、存储过程、触发器过程以及创建匿名块等。 本文介绍Vastbase中PL/pgSQL的执行流程&#xff0c;包括PL/pgSQL的编译与运行。 1、编译 PL/pgSQL的编译…