首页 文章 精选 留言 我的

精选列表

搜索[快速],共10000篇文章
优秀的个人博客,低调大师

JeeSite Vue 5.0.4 发布,Spring Boot 快速开发平台

升级内容 新增 ListSelect 列表选择组件 新增 锁屏密码支持账号密码解锁 新增 后台页面黑暗主题,流程图黑暗主题下调色 优化 避免文件名过长挤出操作列 优化 文件下载显示原文件名 优化 checkImgType 支持 base64 格式 修正 上传文件个数判断差 1 个 修正 Switch 为 false 的时候 foramt 不调用问题 修正 展开的表格不显示水平滚动条问题 修正 展开的表格双击展开图标的时候显示加载框问题 修正 使用展开表格时拖拽报错问题 升级方法 请与jeesite-vue代码仓库源码进行同步,合并代码,手动解决冲突代码。 前端与后端版本不同,匹配后端版本为JeeSite v5.0.2 后端升级内容 Spring Boot 2.5.13、Shiro 1.9.0 等等 新增 Dao 批量操作等系列的方法 新增 BootStrap CSS 的黑暗主题模式 新增 Spring configuration metadata yml 配置信息友好提示 新增 是否启用默认 Servlet 映射(启用后可访问 webapp 下的静态资源访问) 新增 支持 Spring Boot 带减号的 key 写法,自动转换为驼峰格式 新增 BPM 查询全部待办、已办流程数据接口 新增 OAuth2 state 缓存集群共享 新增 CacheUtils exists 方法 优化 去掉 Service 类上的事务注解,方便用户二开开定义 优化 切换租户条件改为权限方式,有租户管理权限的既有切换租户权限 优化 ListUtils.pageList 共 1 页的时候直接返回 优化 mime 加载,避免第三方包里含 mine.types 导致加载不正确 优化 Swagger 文档配置,内置功能增加中文解释。 优化 已经登录的账号,正常返回登录失败信息,方便前端判断 优化 DiffDataUtils 差异比较工具,新增 DiffOptions 差异比较选项,自定义包含和排除等设置 优化 便捷脚本、Docker脚本优化、Maven配置优化 优化 CacheUtils 不存储当前用户信息,防止流程标题生成串用户 优化 多线程,Redis 消息监听线程池、用户缓存清理线程池、消息推送线程池,避免高并发情况下太多的线程问题。 优化 服务器监控磁盘列表,隐藏一些不必要的盘符 优化 访问日志的控制台日志信息输出 优化 Cloud网关路由简化配置 修正 删除用户没有及时清除 session 问题 pr!22 修正 BPM 流程异步事件微服务下不执行问题 升级 Shardingsphere 5.1.1 分库分表框架 可视化数据大屏升级 Avue-data v2.3 无用户数限制,无在线人数限制 后端升级方法 修改pom.xml文件中的jeesite-parent版本号为5.0.2-SNAPSHOT 如果你导入了jeesite-common源码项目,请与git上的代码进行同步 如果你导入了jeesite-module-core源码项目,请与git上的代码进行同步 如果你是跨版本升级,请注意每一个版本的升级方法,业务上有调整的地方进行修改 Shiro 升级到 1.9.0 shiroFilter 方法 getInstance() 替换为 getObject() 执行root/package.bat(sh)打包脚本,强制更新依赖即可。 了解更多 JeeSite 官网地址:http://jeesite.com JeeSite 在线文档:http://docs.jeesite.com JeeSite 演示地址:http://demo.jeesite.com JeeSiteVue演示地址:http://vue.jeesite.com

优秀的个人博客,低调大师

JeeSite Vue 5.0.3 发布,Spring Boot 快速开发平台

升级内容 新增 在线用户列表界面、3分钟内活动的用户、游客用户、强踢 新增 访问日志界面功能、异常日志、修正前后数据对比 新增 菜单管理子系统管理、右上角用户切换子系统 新增 多租户切换功能、页面缓存接口优化 新增 左树右表可拖拽调整大小 by Oliver 新增 BasicTable 表格列拖拽调整列宽功能 新增 BasicTable 树表的本地数据,展开折叠 新增 BasicTable 组件,字典类型,显示字典默认值属性 defaultValue 新增 BasicForm 表单 None 空组件,用于占位 新增 useDict 字典工具新增 initGetDictList 方法,便捷获取字典信息 新增 DictLabel 组件支持这种写法 tag red badge bg-red 多重写法 优化 内置功能体验,状态下拉框,切换后立即查询,不用点击查询按钮 优化 BasicTable 树表展开节点,异步加载性能优化 优化 BasicTable 避免 selection-change 重复调用,有数据时再调用 优化 BasicTable 单元格编辑的自动取消功能,支持除了 Input 组件外的所有组件自动取消 优化 BasicTable 单元格编辑,增加 editAutoCancel 参数,默认为不自动取消 优化 BasicForm 调整 onChange 的执行顺序,放到设置表单 Model 后 优化 BasicForm 允许表单标签 label 为空,省去设置,为空的时候不显示标签 优化 Drawer 和 Modal 当不显示确定的时候,取消按钮默认为关闭字样 优化 Dropdown 组件,保留字问题 key 修改为 value 优化 Dropdown 组件,未设置图标的时候不显示空图标 优化 缩短登录的连接超时时间,增加连接服务器超时和网络问题提示信息 优化 Vue ErrorHandle 全局错误句柄的页面布局及细节 修正 Tree 的 setCheckedKeys 方法,如果设置了空值,就报空的问题 修正 DictLabel 组件 列表上停用启用没有及时更新的问题 修正 BasicTable 编辑表格不显示数值或布尔类型的数据问题 无用户数限制,无在线人数限制 其它细节更多优化改进 升级方法 请与jeesite-vue代码仓库源码进行同步,合并代码,手动解决冲突代码。 后端请更新 LoginController 和 CorpAdminController java 类 前端与后端版本不同,匹配后端版本为JeeSite v5.0.1 了解更多 JeeSite 官网地址:http://jeesite.com JeeSite 在线文档:http://docs.jeesite.com JeeSite 演示地址:http://demo.jeesite.com JeeSiteVue演示地址:http://vue.jeesite.com

优秀的个人博客,低调大师

EE 2.0.3 发布,快速开发跨平台桌面软件

一个入门简单、跨平台桌面软件开发框架。 为什么使用?桌面软件(办公方向、 个人工具),仍然是未来十几年PC端需求之一,提高工作效率 🏆 码云最有价值开源项目 地址:https://gitee.com/wallace5303/electron-egg 地址:https://github.com/wallace5303/electron-egg 5分钟教程,立刻体验 特性 跨平台:一套代码,可以打包成windows版、Mac版、Linux版运行 简单:只需学习 js 语言,支持vue、react、html等前端技术 工程化:可以用服务端的开发思维,来编写桌面软件 高性能:事件驱动、非阻塞式IO 功能丰富:前端、服务端的技术场景都可以使用 功能demo:桌面软件常见功能,后续逐步集成并完善或提供demo 本次更新 增加html模式,前端支持多个html页面 增加socket服务,第三方应用可调用EE应用 增加全局config属性: userHome、appVersion、isPackaged、execDir 增加Utils工具类方法,获取socket端口,socket频道 优化应用创建逻辑 优化配置文件 优化pkg方法 优化动态端口获取 使用场景 1. 常规桌面软件 windows平台 macOS平台 linux平台 (ubuntu) 2. vue、react、web 转换成桌面软件 vue-ant-design(本地) 禅道项目管理(web项目地址) 访问官网:https://www.yuque.com/u34495/mivcfg

优秀的个人博客,低调大师

Appsmith v1.6.12 发布,应用快速构建框架

Appsmith 是一个用于构建管理面板、CRUD 应用程序和工作流的框架,它允许拖放组件来构建仪表板、使用 JavaScript 对象编写逻辑并连接到任何 API、数据库或 GraphQL 源。 目前 Appsmith 发布了 1.6.12 版本,带来如下改动: 新特性 应用程序列表页面的响应式移动 UI#10255 S3 插件:添加一次删除多个文件的命令#11119 能够通过富文本编辑器的工具栏插入媒体和更多格式#11052 支持使用自签名证书运行的 REST API #11043 禁用通过管理设置页面配置的表单登录#11234 支持 GET 请求中的请求正文#7127 添加对处理逗号分隔的浮点值的支持#11207 相机小部件中的多项增强功能#10943 Ansible 支持在 Amazon Linux 上部署#10466 Bug修复 修复复选框表单控件的顶部边距问题#10930 修复 Firestore where 子句不获取数字#10775 修复启用多选时表格小部件中的“全选和取消全选”问题#10838 修复位置更改并打开居中选项时地图图钉不居中的问题#10296 修复 Phone Input 和 Input 小部件在提交问题时未重置的问题#10860 修复文本小部件中的标题标签样式不正确的问题#10949 实体资源管理器中的条目现在会自动排序#10777 修复查询中数字占位符的顺序问题#11005 修复 API URL 编辑器,以垂直扩展长 URL#10663 修复评论图标隐藏在选项卡小部件的选项卡后面的问题#11019 修复 Google 表格因混合数据类型而合并失败的问题#11089 更新公告:https://github.com/appsmithorg/appsmith/releases/tag/v1.6.12

优秀的个人博客,低调大师

Appsmith v1.6.9 发布,应用快速构建框架

Appsmith 是一个用于构建管理面板、CRUD 应用程序和工作流的框架,它允许拖放组件来构建仪表板、使用 JavaScript 对象编写逻辑并连接到任何 API、数据库或 GraphQL 源。 目前 Appsmith 发布了 1.6.9 版本,带来如下改动: 特性 添加 Helm configMap 以更新应用程序配置 (#10157) 实体资源管理器改造:现在实体资源管理器仅显示选定的页面实体,减少了具有多个页面的应用程序的混乱。(#9811) Bug 修复 修复 Select 和 Treeselect WIdget 的验证 (#10760) 添加 iFrame ,用于在文档查看器中加载 Base64 PDF 数据 (#10770) 评估 PrivateWidgets ,以修复列表小部件子组件评估问题 (#10737) 重新验证脚本不加载的问题 (#10764) 当应用程序连接到 git 时,为重定向 url 添加分支参数,同时授权 Google Sheet (#10715) 将查询参数添加到选项/表单 (#10681) 将 meta 添加到 eval 循环,并在默认值更改时更新它 (#10401) 当代码中存在未使用的变量时显示 lint (#10599) 从源应用程序复制克隆应用程序的评估版本,以修复动态动态绑定评估,进而支持没有双重转义的转义字符 (#10702) 图标按钮移除默认的绿色 (#10573) 重置密码时清空会话 (#9955) 更新公告:https://github.com/appsmithorg/appsmith/releases/tag/v1.6.9

优秀的个人博客,低调大师

CakePHP 4.3.0 版本正式发布,PHP 快速开发框架

CakePHP 发布了4.3.0 正式版,CakePHP 是一个运用了诸如 ActiveRecord、Association Data Mapping、Front Controller 和 MVC(model–view–controller) 等著名设计模式的开源 Web 框架,用 PHP 编写,以 Ruby on Rails 的概念为模型,并在 MIT 许可下进行分发。 主要更新: 添加了一个新的 fixture 系统,它允许使用现有的migrations或 SQL 转储文件来定义架构,(包括支持 cake's migrations 和SQL 转储文件)。 加入TestSuite\HttpMockTrait,便于模拟 HTTP 客户端请求 加入LocatorAwareTrait::fetchTable(),让getTableLocator()->get()更符合人体工程学。 加入Controller::middleware(),这个方法可以定义特定于控制器的中间件,或者当前控制器的操作。 deprecationWarning()不再发出重复的警告。 Form对象支持多个验证器,并利用与 ORM 类似的接口来使用这些验证器。 Logged SQL查询现在使用布尔值,更容易粘贴到 repl 里面。 cake console指令被提取到一个新的cakephp/repl包中。 CspMiddleware可以透明地添加基于nonce的策略。 FormHelper将自动设置其他 ARIA 属性。 ORM 现在可以清楚地将用户时区的日期和时间设置为应用的时区。 CakePHP 的依赖组件league/container升级到 4.1.1 版本。 更新公告:https://github.com/cakephp/cakephp/releases/tag/4.3.0

优秀的个人博客,低调大师

深入解析,快速教会你 SQL 子查询优化!

子查询(Subquery)的优化一直以来都是 SQL 查询优化中的难点之一。关联子查询的基本执行方式类似于 Nested-Loop,但是这种执行方式的效率常常低到难以忍受。当数据量稍大时,必须在优化器中对其进行去关联化(Decoorelation 或 Unnesting),将其改写为类似于 Semi-Join 这样的更高效的算子。 前人已经总结出一套完整的方法论,理论上能对任意一个查询进行去关联化。本文结合 SQL Server 以及 HyPer 的几篇经典论文,由浅入深地讲解一下这套去关联化的理论体系。它们二者所用的方法大同小异,基本思想是想通的。 子查询简介 子查询是定义在 SQL 标准中一种语法,它可以出现在 SQL 的几乎任何地方,包括 SELECT, FROM, WHERE 等子句中。 总的来说,子查询可以分为关联子查询(Correlated Subquery)和非关联子查询(Non-correlated Subquery)。后者非关联子查询是个很简单的问题,最简单地,只要先执行它、得到结果集并物化,再执行外层查询即可。下面是一个例子: SELECT c_count, count(*) AS custdist FROM ( SELECT c_custkey, count(o_orderkey) AS c_count FROM CUSTOMER LEFT OUTER JOIN ORDERS ON c_custkey = o_custkey AND o_comment NOT LIKE '%pending%deposits%' GROUP BY c_custkey ) c_orders GROUP BY c_count ORDER BY custdist DESC, c_count DESC; 非关联子查询不在本文讨论范围之列,除非特别声明,以下我们说的子查询都是指关联子查询。 关联子查询的特别之处在于,其本身是不完整的:它的闭包中包含一些外层查询提供的参数。显然,只有知道这些参数才能运行该查询,所以我们不能像对待非关联子查询那样。 根据产生的数据来分类,子查询可以分成以下几种: 标量(Scalar-valued)子查询:输出一个只有一行一列的结果表,这个标量值就是它的结果。如果结果为空(0 行),则输出一个 NULL。但是注意,超过 1 行结果是不被允许的,会产生一个运行时异常。 标量子查询可以出现在任意包含标量的地方,例如 SELECT、WHERE 等子句里。下面是一个例子: SELECT c_custkey FROM CUSTOMER WHERE 1000000 < ( SELECT SUM(o_totalprice) FROM ORDERS WHERE o_custkey = c_custkey ) Query 1: 一个出现在 WHERE 子句中的标量子查询,关联参数用红色字体标明了 SELECT o_orderkey, ( SELECT c_name FROM CUSTOMER WHERE c_custkey = o_custkey ) AS c_name FROM ORDERS Query 2: 一个出现在 SELECT 子句中的标量子查询 存在性检测(Existential Test)子查询:特指 EXISTS 的子查询,返回一个布尔值。如果出现在 WHERE 中,这就是我们熟悉的 Semi-Join。当然,它可能出现在任何可以放布尔值的地方。 SELECT c_custkey FROM CUSTOMER WHERE c_nationkey = 86 AND EXISTS( SELECT * FROM ORDERS WHERE o_custkey = c_custkey ) Query 3: 一个 Semi-Join 的例子 集合比较(Quantified Comparision)子查询:特指 IN、SOME、ANY 的查询,返回一个布尔值,常用的形式有:x = SOME(Q)(等价于x IN Q)或X &lt;&gt; ALL(Q)(等价于x NOT IN Q)。同上,它可能出现在任何可以放布尔值的地方。 SELECT c_name FROM CUSTOMER WHERE c_nationkey <> ALL (SELECT s_nationkey FROM SUPPLIER) Query 4: 一个集合比较的非关联子查询 原始执行计划 我们以 Query 1 为例,直观地感受一下,为什么说关联子查询的去关联化是十分必要的。 下面是 Query 1 的未经去关联化的原始查询计划(Relation Tree)。与其他查询计划不一样的是,我们特地画出了表达式树(Expression Tree),可以清晰地看到:子查询是实际上是挂在 Filter 的条件表达式下面的。 实际执行时,查询计划执行器(Executor)在执行到 Filter 时,调用表达式执行器(Evaluator);由于这个条件表达式中包含一个标量子查询,所以 Evaluator 又会调用 Executor 计算标量子查询的结果。 这种 Executor - Evaluator - Executor 的交替调用十分低效!考虑到 Filter 上可能会有上百万行数据经过,如果为每行数据都执行一次子查询,那查询执行的总时长显然是不可接受的。 Apply 算子 上文说到的 Relation - Expression - Relation 这种交替引用不仅执行性能堪忧,而且,对于优化器也是个麻烦的存在——我们的优化规则都是在匹配并且对 Relation 进行变换,而这里的子查询却藏在 Expression 里,令人无从下手。 为此,在开始去关联化之前,我们引入 Apply 算子: Apply 算子(也称作 Correlated Join)接收两个关系树的输入,与一般 Join 不同的是,Apply 的 Inner 输入(图中是右子树)是一个带有参数的关系树。 Apply 的含义用下图右半部分的集合表达式定义:对于 Outer Relation RR 中的每一条数据 rr,计算 Inner Relation E(r)E(r),输出它们连接(Join)起来的结果 r⊗E(r)r⊗E(r)。Apply 的结果是所有这些结果的并集(本文中说的并集指的是 Bag 语义下的并集,也就是 UNION ALL)。 Apply 是 SQL Server 的命名,它在 HyPer 的文章中叫做 Correlated Join。它们是完全等价的。考虑到 SQL Server 的文章发表更早、影响更广,本文中都沿用它的命名。 根据连接方式(⊗⊗)的不同,Apply 又有 4 种形式: Cross ApplyA×A×:这是最基本的形式,行为刚刚我们已经描述过了; Left Outer ApplyALOJALOJ:即使 E(r)E(r) 为空,也生成一个 r∘{NULLs}r∘{NULLs}。 Semi ApplyA∃A∃:如果 E(r)E(r) 不为空则返回 rr,否则丢弃; Anti-Semi ApplyA∄A∄:如果 E(r)E(r) 为空则返回 rr,否则丢弃; 我们用刚刚定义的 Apply 算子来改写之前的例子:把子查询从 Expression 内部提取出来。结果如下: 上面的例子中,我们可以肯定 Scalar Agg 子查询有且只有一行结果,所以可以直接转成 Apply。但某些情况下,可能无法肯定子查询一定能返回 0 或 1 行结果(例如,想象一下 Query 2 如果 c_custkey 不是唯一的),为了确保 SQL 语义,还要在 Apply 右边加一个 Max1RowMax1Row 算子: Max1Row(E)=⎧⎩⎨⎪⎪Null,E,error,if |E|=0if |E|=1otherwiseMax1Row(E)={Null,if |E|=0E,if |E|=1error,otherwise 理论上,我们可以将所有的子查询转换成 Apply 算子,一个通用的方法如下: 1.如果某个算子的表达式中出现了子查询,我们就把这个子查询提取到该算子下面(留下一个子查询的结果变量),构成一个 ALOJALOJ 算子。如果不止一个子查询,则会产生多个 ALOJALOJ。必要的时候加上 Max1RowMax1Row 算子。 2.然后应用其他一些规则,将 ALOJALOJ 转换成 A×A×、A∃A∃、A∄A∄。例如上面例子中的子查询结果 XX 被用作 Filter 的过滤条件,NULL 值会被过滤掉,因此可以安全地转换成 A×A×。 下面这个例子中,Filter 条件表达式中包含 Q1Q1、Q2Q2 两个子查询。转换之后分别生成了对应的 Apply 算子。其中 Q2Q2 无法确定只会生成恰好一条记录,所以还加上了 Max1RowMax1Row 算子。 基本消除规则 第一组规则是最基本的规则,等式中的 ⊗⊗ 说明它不限制连接类型,可以是 {×,LOJ,∃,∄}{×,LOJ,∃,∄} 中的任意一个。 这两条规则是非常显而易见的,翻译成大白话就是:如果 Apply 的右边不包含来自左边的参数,那它就和直接 Join 是等价的。 下面是对 Query 3 应用规则 (2) 的例子: Project 和 Filter 的去关联化 第二组规则描述了如何处理子查询中的 Project 和 Filter,其思想可以用一句话来描述:尽可能把 Apply 往下推、把 Apply 下面的算子向上提。 注意这些规则仅处理 Cross Apply 这一种情况。其他 3 种 Apply 的变体,理论上都可以转换成 Cross Apply,暂时我们只要知道这个事实就可以了。 你可能会问:通常我们都是尽可能把 Filter、Project 往下推,为什么这里会反其道而行呢?关键在于:Filter、Project 里面原本包含了带有关联变量的表达式,但是把它提到 Apply 上方之后,关联变量就变成普通变量了!这正是我们想要的。 我们稍后就会看到这样做的巨大收益:当 Apply 被推最下面时,就可以应用第一组规则,直接把 Apply 变成 Join,也就完成了子查询去关联化的优化过程。 下面是对 Query 2 应用规则 (3) 的例子。之后再应用规则 (1),就完成了去关联化过程。 Aggregate 的去关联化 第三组规则描述如何处理子查询中的 Aggregate(即 Group By)。和上一组一样,我们的指导思想仍然是:尽可能把 Apply 往下推、把 Apply 下面的算子向上提。 下面等式中,GA,FGA,F 表示带有 Group By 分组的聚合(Group Agg),其中 AA 表示分组的列,FF 表示聚合函数的列;G1FGF1 表示不带有分组的聚合(Scalar Agg)。 这一组规则不像之前那么简单直白,我们先看一个例子找找感觉。下面是对 Query 1 运用规则 (9) 的结果: 规则 (9) 在下推 Apply 的同时,还将 ScalarAgg 变成了 GroupAgg,其中,分组列就是 R 的 key,在这里也就是 CUSTOMER 的主键 c_custkey。 如果 R 没有主键或唯一键,理论上,我们可以在 Scan 时生成一个。 为什么变换前后是等价的呢?变换前,我们是给每个 R 的行做了一次 ScalarAgg 聚合计算,然后再把聚合的结果合并起来;变换后,我们先是将所有要聚合的数据准备好(这被称为 augment),然后使用 GroupAgg 一次性地做完所有聚合。 这也解释了为什么我们要用 ALOJALOJ 而不是原本的 A×A× :原来的 ScalarAgg 上,即使输入是空集,也会输出一个 NULL。如果我们这里用 ALOJALOJ,恰好也会得到一样的行为(*);反之,如果用 A×A× 就有问题了——没有对应 ORDERS 的客户在结果中消失了! 规则 (8) 处理的是 GroupAgg,道理也是一样的,只不过原来的分组列也要留着。 ScalarAgg 转换中的细节* 细心的读者可能注意到,规则 (9) 右边产生的聚合函数是 F′F′,多了一个单引号,这暗示它和原来的聚合函数 FF 可能是有些不同的。那什么情况下会不同呢?这个话题比较深入了,不感兴趣的同学可以跳过。 首先我们思考下,GroupAgg 以及 ALOJALOJ 的行为真的和变换前一模一样吗?其实不然。举个反例: SELECT c_custkey, ( SELECT COUNT(*) FROM ORDERS WHERE o_custkey = c_custkey ) AS count_orders FROM CUSTOMER 设想一下:客户 Eric 没有任何订单,那么这个查询应当返回一个['Eric', 0]的行。但是,当我们应用了规则 (9) 做变换之后,却得到了一个['Eric', 1]的值,结果出错了! 为何会这样呢?变换之后,我们是先用 LeftOuterJoin 准备好中间数据(augment),然后用 GroupAgg 做聚合。LeftOuterJoin 为客户 Eric 生成了一个['Eric', NULL, NULL, ...]的行;之后的 GroupAgg 中,聚合函数COUNT(*)认为 Eric 这个分组有 1 行数据,所以输出了['Eric', 1]。 下面是个更复杂的例子,也有类似的问题: SELECT c_custkey FROM CUSTOMER WHERE 200000 < ( SELECT MAX(IF_NULL(o_totalprice, 42)) -- o_totalprice may be NULL FROM ORDERS WHERE o_custkey = c_custkey ) 作为总结,问题的根源在于:F(∅)≠F({NULL})F(∅)≠F({NULL}),这样的聚合函数 FF 都有这个问题。 变换后的 GroupAgg 无法区分它看到的 NULL 数据到底是 OuterJoin 产生的,还是原本就存在的,有时候,这两种情形在变换前的 ScalarAgg 中会产生不同的结果。 幸运的是,SQL 标准中定义的聚合函数 F(col)F(col) 都是 OK 的——它们都满足 F(∅)=F({NULL})F(∅)=F({NULL}),我们只要对 FF 稍加变换就能解决这个问题。 对于例子一,将COUNT(*)替换成一个对非空列(例如主键)的 Count 即可,例如:COUNT(o_orderkey); 对于例子二,需要把MIN(IF_NULL(o_totalprice, 42))分成两步来做:定义中间变量X,先用 Project 计算X = IF_NULL(o_totalprice, 42),再对聚合函数MIN(X)进行去关联化即可。 集合运算的去关联化 最后一组优化规则用来处理带有 Union(对应UNION ALL)、Subtract(对应EXCEPT ALL) 和 Inner Join 算子的子查询。再强调一遍,我们的指导思想是:尽可能把 Apply 往下推、把 Apply 下面的算子向上提。 下面的等式中,×× 表示 Cross Join,⋈R.key⋈R.key 表示按照 RR 的 Key 做自然连接:r∘e1∘e2r∘e1∘e2 。和之前一样,我们假设 RR 存在主键或唯一键,如果没有也可以在 Scan 的时候加上一个。 注意到,这些规则与之前我们见过的规则有个显著的不同:等式右边 RR 出现了两次。这样一来,要么我们把这颗子树拷贝一份,要么做成一个 DAG 的执行计划,总之会麻烦许多。 事实上,这一组规则很少能派上用场。在 [2] 中提到,在 TPC-H 的 Schema 下甚至很难写出一个带有 Union All 的、有意义的子查询。 其他 有几个我认为比较重要的点,用 FAQ 的形式列在下面。 ► 是否任意的关联子查询都可以被去关联化? 可以说是这样的,在加上少量限定之后,理论上可以证明:任意的关联子查询都可以被去关联化。 证明方法在 [1]、[3] 中都有提及。以 [1] 中为例,思路大致是: 对于任意的查询关系树,首先将关联子查询从表达式中提取出来,用 Apply 算子表示; 一步步去掉其中非基本关系算子,首先,通过等价变换去掉 Union 和 Subtract; 进一步缩小算子集合,去掉 OuterJoin、ALOJALOJ、A∃A∃、A∄A∄; 最后,去掉所有的 A×A×,剩下的关系树仅包含基本的一些关系算子,即完成了去关联化。 另一方面,现实世界中用户使用的子查询大多是比较简单的,本文中描述的这些规则可能已经覆盖到 99% 的场景。虽然理论上任意子查询都可以处理,但是实际上,没有任何一个已知的 DBMS 实现了所有这些变换规则。 ► HyPer 和 SQL Server 的做法有什么异同? HyPer 的理论覆盖了更多的去关联化场景。例如各种 Join 等算子,[3] 中都给出了相应的等价变换规则(作为例子,下图是对 Outer Join 的变换)。而在 [1] 中仅仅是证明了这些情况都可以被规约到可处理的情形(实际上嘛,可想而知,一定是没有处理的)。 另一个细节是,HyPer 中还存在这样一条规则: 其中,D=ΠF(T2)∩A(T1)(T1)D=ΠF(T2)∩A(T1)(T1),表示对 T1T1 的 Distinct Project 结果(所谓的Magic Set)。直接看等式比较晦涩,看下面的例子就容易理解了: 图中,在做 Apply 之前,先拿到需要 Apply 的列的 Distinct 值集合,拿这些值做 Apply,之后再用普通的 Join 把 Apply 的结果连接上去。 这样做的好处是:如果被 Apply 的数据存在大量重复,则 Distinct Project 之后需要 Apply 的行数大大减少。这样一来,即使之后 Apply 没有被优化掉,迭代执行的代价也会减小不少。 ► 本文说的这些变换规则,应该用在 RBO 还是 CBO 中呢?换句话说,去关联化后之后的执行计划一定比去关联化之前更好吗? 答案是,不一定。 直观的看,如果 Apply 的左边数据量比较少(例如,仅有 1 条数据),那直接带入 Apply 的右边计算反而是更好的方式。另一种情况是,右边有合适的索引,这种情况下,多次 Apply 的代价也并非不可接受。 所以把这些规则放进一个 CBO 的优化器是更合适的,优化器根据代价估计选出最优的计划来。甚至,在某些情况下,我们还会自右向左地运用这些等式,做“加关联化”。 这和用 HashJoin 还是 NestedLoopJoin 是同样的道理。事实上,NestedLoopJoin 就是 Apply 的一个特例。如果存在合适的索引,NestedLoopJoin 效率高于 HashJoin 是很常见的事情。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册