首页 文章 精选 留言 我的

精选列表

搜索[内核],共10002篇文章
优秀的个人博客,低调大师

openGauss内核分析之查询重写

目录 查询重写介绍 示例:外连接消除Outer2Inner 查询重写介绍 SQL语言是丰富多样的,非常的灵活,不同的开发人员依据经验的不同,手写的SQL语句也是各式各样,另外还可以通过工具自动生成。SQL语言是一种描述性语言,数据库的使用者只是描述了想要的结果,而不关心数据的具体获取方式,输入数据库的SQL语言很难做到是以最优形式表示的,往往隐含了一些冗余信息,这些信息可以被挖掘用来生成更加高效的SQL语句。查询重写就是把用户输入的SQL语句转换为更高效的等价SQL,查询重写遵循两个基本原则。 等价性:原语句和重写后的语句,输出结果相同。 高效性:重写后的语句,比原语句在执行时间和资源使用上更高效。 查询重写优化既可以基于关系代数的理论进行优化,例如谓词下推、子查询优化等,也可以基于启发式规则进行优化,例如Outer Join消除、表连接消除等。查询重写是基于规则的逻辑优化。 在代码层面,查询重写的架构如下: 下面以外连接消除Outer2Inner—外连接转内连接为例分析查询重写过程:在left outer join或者right outer join中,如果查询条件中存在逻辑上能够包含IS NOT NULL,例如c1 > 0,可以将查询转换成INNER JOIN,从而减少关联处理产生的中间结果集。 示例:外连接消除Outer2Inner 下面首先以一个例子来说明各种多表连接方式的区别: create table t1(c1 int, c2 int); create table t2(c1 int, c2 int); insert into t1 values(1, 10); insert into t1 values(2, 20); insert into t1 values(3, 30); insert into t2 values(1, 100); insert into t2 values(3, 300); insert into t2 values(5, 500); 内连接inner join:返回两个表都满足的组合,相当于取两个表的交集。 SELECT * FROM t1 inner JOIN t2 ON t1.c1 = t2.c1; 左连接 left outer join:返回左表中的所有行,如果左表中行在右表中没有匹配行,则结果中右表中的列返回空值。 SELECT * FROM t1 Left OUTER JOIN t2 ON t1.c1 = t2.c1; 右连接 right outer join:返回右表中的所有行,如果右表中行在左表中没有匹配行,则结果中左表中的列返回空值。 SELECT * FROM t1 right OUTER JOIN t2 ON t1.c1 = t2.c1; 全连接 full join:返回左表和右表中的所有行。当某行在另一表中没有匹配行,则另一表中的列返回空值,相当于取两个表并集。 SELECT * FROM t1 full JOIN t2 ON t1.c1 = t2.c1; 在以上实验的基础上增加t2表的where条件。 left join和inner join的结果是一样的,这是因为查询条件中包含WHERE t2.c2 >100这个条件,t2表所有不匹配元组均被过滤掉(包括空值),因此可以进行查询转换left-outer join -> inner join,能够有效减小t1和t2关联产生的结果集,达到性能提升的目的。 在openGauss数据库系统中,subquery_planner会遍历查询树中的rtable,看看是否有RTE_JOIN类型的节点存在,设置hasOuterJoins标志量,从而进入到reduce_outer_joins接口,满足外连接消除条件时再执行外连接的消除。reduce_outer_Joins函数内部做两个动作: (1)reduce_outer_joins_pass1预检查,就是检查jointree中是否含有外链接,以及一些引用表的信息,为动作2做好信息采集准备,重点参考数据结构reduce_outer_joins_state; (2)reduce_outer_joins_pass2真正完成消除外链接。 void reduce_outer_joins(PlannerInfo* root) { reduce_outer_joins_state* state = NULL; state = reduce_outer_joins_pass1((Node*)root->parse->jointree); /* planner.c shouldn't have called me if no outer joins */ if (state == NULL || !state->contains_outer) ereport(ERROR, (errmodule(MOD_OPT), errcode(ERRCODE_OPTIMIZER_INCONSISTENT_STATE), (errmsg("so where are the outer joins?")))); reduce_outer_joins_pass2((Node*)root->parse->jointree, state, root, NULL, NIL, NIL); } 利用上一期的分析方法,可以得到查询树内存结构(查询树Query结构体中targetList存储目标属性语义分析结果,rtable存储FROM子句生成的范围表,jointree的quals字段存储WHERE子句语义分析的表达式树) 对比reduce_outer_joins运行前后查询树,jointree和rtable中的jointype都由join_left转换为join_inner,即外连接已转为内连接。 (gdb) p *((JoinExpr*)(parse->jointree->fromlist->head.data->ptr_value)) $1 = {type = T_JoinExpr, jointype = JOIN_INNER, isNatural = false, larg = 0x7fdfb345cd08, rarg = 0x7fdfb345e2e8, usingClause = 0x0, quals = 0x7fdfb2f0b8a8, alias = 0x0, rtindex = 3} (gdb) p *(RangeTblEntry*)(parse->rtable->tail.data->ptr_value) $2 = {type = T_RangeTblEntry, rtekind = RTE_JOIN, relname = 0x0, partAttrNum = 0x0, relid = 0, partitionOid = 0, isContainPartition = false, subpartitionOid = 0, isContainSubPartition = false, refSynOid = 0, partid_list = 0x0, relkind = 0 '\000', isResultRel = false, tablesample = 0x0, timecapsule = 0x0, ispartrel = false, ignoreResetRelid = false, subquery = 0x0, security_barrier = false, jointype = JOIN_INNER, …}

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

Android内核剖析读书笔记

第16章 程序包管理 PackageManagerService類 PmS 目錄 16.1 包管理概述 16.2 packages.xml文件格式 16.3 包管理服務的啟動過程 16.4 應用程序的安裝和卸載 16.5 intent匹配框架 16.1 包管理概述 1.包管理服務的程序結構 分別為應用程序層,PmS服務層,及數據文件層 應用程序層 DontextImpl.ApplicationPackageManager Pms服務層 /data/system/packages.xml 所有应用程序与包管理相关信息 /system/etc/permisions/xxx.xml 加载系统feature,并为核心系统进程分配默认权限 PackageManagerService DefaultContainerService : 把安裝程序複製到程序目錄中。 Installer: 實際上是一個Socket客戶端。 程序文件層 /system/app 系统自带应用程序路径 /data/app 第三方应用程序层 /data/dalvik-cache/dex文件输出路径 /system/framework/*.apk;*.jar framework中的程序 /data/secure 加密文件 /data/drm/ drm用户专有目录 /data/app-private/drm用户专有目录 /data/data/ 普通程序数据 16.2 packages.xml文件格式 保存在 /data/system目錄下,裏面有很多標籤,如last-platform-version, permission-trees等。 16.3 包管理服務的啟動過程 包管理服務的啟動過程實際上市讀取XML文件中的信息,并把這些信息存放到相關的類成員變量中。 1.創建PmS。Settings對象 2.mSettings.addShareduserLP() 添加四個共享id。 3.創建一個Installer對象,該對象將輔助程序的安裝。 4.給幾個數據文件賦值。如mAppDataDir,mSecureAppDataDir,mDrmAppPrivateInstallDir。 5.調用readPermission函數。 6.調用沒Setting對象的readLP函數,讀取應用程序和包管理相關信息。 7.對java系統中的庫進行dex提取。 8為三個程序目錄創建一個FileObserver。FileObserver对象内部会检测目录中的添加、删除事件。這三個目錄是 /system/frameworks: 该目录保存了framework內核相關程序 /system/app:系统程序 /verdor/app:第三方程序,一般指厂商开发的自定义程序。 9 调用scanDirLI()掃描(解析程序中的Androidmanifest.xml)以上三個目錄中的所有程序文件,并將掃描結果放到PmS中的mPackages變量中。 10 刪除已經不存在程序對應的數據記錄。 11 清除沒有安裝成功的數據記錄。 12 為一下兩個第三方程序目錄添加FileObserver,并調用scanDirLI()解析目錄下所有的應用程序。 這連個目錄如下。 /data/app: 普通應用程序目錄。 /data/app-private: 該目錄沒錢并沒有被使用。 13 刪除/data/app目錄下以vmdl開頭及以.tmp结尾的文件。 14 如果系統版本升級,調用updatePermissionLP() 重新為應用程序賦予權限。 15 調用writeLP() 將mPackages中的數據重新寫入packages.xml文件中。 以上就是Pms啟動的主體功能。 16.4 應用程序的安裝和卸載 安裝和卸載應用程序都由PmS完成。安裝程序的過程包括在程序目錄下創建以包命名的程序文件、創建程序數據目錄,以及把程序相關的信息保存到相關的配置文件packages.xml文件中,卸載過程則是相反的操作。 16.5 intent匹配框架 intent匹配主要解決應用程序中沒有明確指定Component名稱的情況。 本文转自Work Hard Work Smart博客园博客,原文链接:http://www.cnblogs.com/linlf03/p/3370227.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

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

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

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

用户登录
用户注册