CN111797112B - 一种PostgreSQL预备语句执行优化方法 - Google Patents
一种PostgreSQL预备语句执行优化方法 Download PDFInfo
- Publication number
- CN111797112B CN111797112B CN202010503294.5A CN202010503294A CN111797112B CN 111797112 B CN111797112 B CN 111797112B CN 202010503294 A CN202010503294 A CN 202010503294A CN 111797112 B CN111797112 B CN 111797112B
- Authority
- CN
- China
- Prior art keywords
- estate
- function
- place
- statement
- plan
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Expired - Fee Related
Links
- 238000002360 preparation method Methods 0.000 title claims abstract description 84
- 238000000034 method Methods 0.000 title claims abstract description 67
- 238000005457 optimization Methods 0.000 title claims abstract description 23
- 230000008569 process Effects 0.000 claims abstract description 31
- 230000006870 function Effects 0.000 claims description 169
- 238000004140 cleaning Methods 0.000 claims description 35
- 230000002068 genetic effect Effects 0.000 claims description 8
- 230000008859 change Effects 0.000 claims description 5
- 150000002148 esters Chemical class 0.000 claims description 5
- 239000011800 void material Substances 0.000 claims 1
- 230000000694 effects Effects 0.000 description 4
- 230000007246 mechanism Effects 0.000 description 2
- 238000007792 addition Methods 0.000 description 1
- 230000009286 beneficial effect Effects 0.000 description 1
- 238000010276 construction Methods 0.000 description 1
- 230000006872 improvement Effects 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/245—Query processing
- G06F16/2453—Query optimisation
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/242—Query formulation
- G06F16/2433—Query languages
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/24—Querying
- G06F16/245—Query processing
- G06F16/2453—Query optimisation
- G06F16/24534—Query rewriting; Transformation
- G06F16/24539—Query rewriting; Transformation using cached or materialised query results
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- Computational Linguistics (AREA)
- Data Mining & Analysis (AREA)
- Databases & Information Systems (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Mathematical Physics (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明公开了一种PostgreSQL预备语句执行优化方法,在方法中提出了缓存预备语句执行过程中的PlanState并重复使用的优化方案。在该优化方案中,当一个预备语句编译执行时,缓存了执行计划后,保存缓存的执行计划被第一次执行时构造的PlanState结构,并在之后的执行中重用保存下来的PlanState,只对结构中部分成员值重新赋值,避免每次执行时重新构造PlanState造成的时间的消耗。该方法通过对PostgreSQL预备语句执行进行优化,从而显著提高了预备语句的执行效率。
Description
技术领域
本发明涉及数据库技术领域,具体涉及一种PostgreSQL预备语句执行优化方法。
背景技术
SQL的执行大致分为解析,优化和执行几个步骤。解析和优化的结果是执行计划,通常相同的SQL语句要被执行很多次,并且每次执行很可能采用的是相同的执行计划。生成执行计划的过程是要花费时间的,特别是对一些复杂SQL。通过使用预备语句,把执行计划缓存起来,下次执行的时候跳过优化这一步,用户可以多次反复绑定不同的参数给这个预备语句,假如这个结构的SQL语句被执行次数很多的话,数据库系统就避免了大量地解析和优化同一结构的SQL语句,从而提升系统性能。
预备语句是当前主流关系数据库都支持的一个功能。PostgreSQL也支持预备语句的功能,当PREPARE语句被执行时,指定的语句会被解析、分析并且重写。当后续发出一个EXECUTE命令时,该预备语句会被规划并且执行。预备语句可以接受参数:在执行时会被替换到语句中的值。在创建预备语句时,可以用位置引用参数。也可以选择性地指定参数数据类型的一个列表。当一个参数的数据类型没有被指定或者被声明为未知时,其类型会从该参数被使用的环境中推知。在执行该语句时,EXECUTE语句中为这些参数指定实际值。预备语句只在当前数据库会话期间存在。当会话结束时,预备语句会消失,因此在重新使用之前必须重新建立它。
本申请发明人在实施本发明的过程中,发现现有技术的方法,至少存在如下技术问题:
PostgreSQL在执行一个SQL过程中时,需要构建一个和plan树结构相同的PlanState树来记录查询树的相关信息。虽然使用预备语句可以节省构建plan树的时间开销,但是每次执行一个查询时依然需要重新构建相应的PlanState树,其构建的开销可能占据到一个查询执行总时间的30%。
由此可知,现有技术中的方法存在执行效率不高的技术问题。
发明内容
本发明主要解决PostgreSQL数据库针对预备语句优化PlanState的生成和使用的技术问题;提供了一种PostgreSQL数据库预备语句优化PlanState的生成和使用的方法,方法主要通过修改源代码,保存第一次构造的PlanState结构,并在之后的执行中重用保存下来的PlanState,只需对结构中部分成员值重新赋值,避免每次执行时重新构造PlanState造成的时间的消耗,从而提高预备语句的执行效率。
为了达到上述技术效果,本发明提供了一种PostgreSQL预备语句执行优化方法,其特征在于,包括:
S1:对执行过程中的相关数据结构进行调整,用以准备执行时需要用的信息,相关数据结构包括执行器状态内存上下文estate_context、全局指针变量、用于预备语句缓存计划的结构体缓存计划CachedPlan以及用于保存查询时需要使用的信息的结构体QueryDesc;
S2:对准备阶段的函数PortalStart进行改动,增加预备语句的判断以及计划是否被缓存的判断过程,其中,函数PortalStart用于根据不同的查询类型选择不同的操作,为执行查询准备一个门户;
S3:对函数standard_ExecutorStart进行改动,增加执行的是否为一个预备语句的判断以及执行器的状态是否被缓存的判断过程,standard_ExecutorStart函数用于准备一个执行计划;
S4:基于S1得到的数据结构、S2得到的PortalStart函数、S3得到的standard_ExecutorStart函数对预备语句进行执行;
S5:在预备语句执行之后,通过修改函数PortalCleanup,使得清理过程中,跳过函数ExecutorEnd对estate,planstate和ExecutorState上下文的清理,创建内存上下文estate_context用以保存ExecutorState上下文,其中,函数PortalCleanup为用于门户清理的函数,estate为执行器调用时的工作状态信息,planstate为计划的状态信息、ExecutorState上下文为执行器状态上下文。
在一种实施方式中,S1具体包括:
S1.1:添加新的内存上下文estate_context,作为TopMemoryContext的子节点,其中,TopMemoryContext为根内存上下文,是所有内存上下文节点的根节点,estate_context内存上下文作用是缓存需要重用的estate和planstate结构所在的内存上下文;
S1.2:添加两个全局变量estate_planstatecache和planstate_planstatecache,分别用于指向要保存的执行器调用时的工作状态信息estate和计划的状态信息planstate;
S1.3:在结构体缓存计划CachedPlan中添加三个成员:
bool is_generic;用于判断一个缓存计划是否为一个一般计划,
Estate*estate_psc;当一个缓存计划为一般计划时,用于保存需要重用的执行器调用时的工作状态信息estate;
PlanState*PlanState;当该cachedplan是一般计划时,用于保存需要重用的计划的状态信息planstate;
S1.4:在QueryDesc结构中添加三个成员:
bool isprep;用于判断一个执行的语句是否为一个prepare的语句;
Estate*estate_psc;用于指向需要重用的执行器调用时的工作状态信息estate;
PlanState*planstate_psc;用于指向需要重用计划的状态信息planstate。
在一种实施方式中,S2具体包括:
在执行CreateQueryDesc创建queryDesc后,通过增加判断语句判断一个语句是否为预备语句,如果不是预备语句,则按照原PortalStart函数流程执行;如果是预备语句,则判断缓存计划是否为一个一般计划,若不是一般计划,则继续按原函数PortalStart流程执行;如果是一般计划,则将queryDesc的成员isprep设置为true,接着判断缓存计划cplan的estate_psc和planstate_psc是否存在,如果不存在则继续按原函数流程执行;如果存在,则将queryDesc的estate_psc和planstate_psc分别指向cplan中的estate_psc和planstate_psc,其中,cplan是一个CachedPlan类型的变量,表示一个缓存计划。
在一种实施方式中,S3具体包括:
在PortalStart函数中创建queryDesc后,接下来调用函数ExecutorStart,ExecutorStart的执行中调用函数standard_ExecutorStart,函数standard_ExecutorStart用于准备一个执行计划,即创建estate和planstate;
在函数standard_ExecutorStart中更改创建estate的步骤;通过增加一个判断语句判断queryDesc->isprep是否为一个预备语句以及queryDesc中的estate_psc是否存在,如果都存在,则将estate指向estate_psc;
否则按正常流程执行创建estate,并且判断如果isprep为true则将全局变量estate_planstatecache指向创建的estate;
切换内存上下文到estate下的es_query_cxt,es_query_cxt为ExcutorState内存上下文,表示在代码中estate的成员变量,然后重新设置部分estate中会变化的字段值,字段值包括:estate的参数列表es_param_list_info,每次都需要根据的执行语句的参数重新绑定。
在一种实施方式中,在函数standard_ExecutorStart中,除了创建estate,还会调用InitPlan函数创建planstate,在InitPlan函数中,调用ExecInitNode先为子计划生成相应的planstate,然后为plan创建相应的planstate,在步骤S3之后,所述方法还包括:
在执行InitPlan时,更改ExecInitNode创建PlanState的步骤,首先判断queryDesc->isprep是否为一个预备语句以及queryDesc中的planstate_psc是否存在,如果都为真则将PlanState指向planstate_psc,并调用函数ResetPlanState对保存下来的estate和planstate进行部分成员值的重置;否则执行ExecInitNode创建一个PlanState,并再次判断如果isprep为真则将全局变量planstate_planstatecache指向创建的planstate。
在一种实施方式中,所述方法还包括:添加函数ResetPlanState:
函数声明为:VoidResetPlanState(PlanState*node,Estate*estate);
在InitPlan中,执行预备语句如果存在保存下来的planstate,在将当前的planstate指向保存下来的planstate,然后执行ResetPlanState重新设置planstate和estate中需要更新的成员,ResetPlanState函数用于根据node类型执行不同的重置操作;
遍历PlanState tree的每个节点,设置planstate和estate中每次执行会变化的字段值,当所有需要改变的字段值设置完成后,继续调用PortalRun函数,其中,PortalRun函数为门户执行函数,用来在PortalStart函数完成所有相关信息准备工作后,执行查询,获取并返回查询语句的执行结果。
在一种实施方式中,函数PortalDrop是进行Portal清理的入口函数,其中通过portal->cleanup函数指针指向PortalCleanup,PortalCleanup函数是进行Portal清理工作的函数之一,对Portal的成员queryDesc及queryDesc下的estate和planstate内容进行清理,S5具体包括:
S5.1:判断portal->cplan是否存在,若不存在说明不是执行预备语句,直接按原步骤执行函数ExecutorEnd;若存在则说明是执行预备语句,然后判断是否存在estate_context内存上下文,不存在则创建,函数ExecutorEnd用于在执行完SQL之后进行清理工作;
S5.2:根据queryDesc->isprep和cplan->is_generic判断是否为一个一般计划,若不是则执行函数ExecutorEnd;若是,则当portal->strategy为PORTAL_ONE_SELECT且estate和planstate还未被缓存,则保存需要重用的estate和planstate,同时将相应的estate的内存上下文es_query_cxt的父节点设置为estate_context。
本申请实施例中的上述一个或多个技术方案,至少具有如下一种或多种技术效果:
现有技术中,一个预备语句被多次执行,每次在PortalStart函数进行执行的相关信息准备时,都要重新创建estate和planstate,本发明的优化方法,通过修改预备语句执行过程中的数据结构、PortalStart函数、standard_ExecutorStart函数、PortalCleanup函数等,使得一个预备语句多次执行时,可以跳过使用函数CreateExecutorState创建estate和使用函数ExecInitNode创建planstate的过程,而是获取被缓存下来的estate和planstate所在的内存上下文ExecutorState,然后切换到该内存上下文得到被缓存的estate和planstate变量,接着调用函数ResetPlanState对两个变量中部分值的进行重新设置,完成PortalStart步骤,然后后续的执行过程PortalRun即可使用缓存的estate和planstate,得到正确的结果。最后的PortalDrop清理,跳过函数ExecutorEnd对estate,planstate和ExecutorState上下文的清理,创建内存上下文estate_context用来保存ExecutorState上下文,从而将estate和planstate缓存下来了,也就是说,本发明的方法只需对结构中部分成员值重新赋值,就可以避免每次执行时重新构造PlanState造成的时间的消耗,故而可以大大提高预备语句的执行效率。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1是本发明提供的一种PostgreSQL预备语句执行优化方法的流程示意图。
具体实施方式
本发明公开了一种PostgreSQL预备语句执行优化的方法,在方法中提出了缓存预备语句执行过程中的PlanState并重复使用的优化方案。在该优化方案中,当一个预备语句编译执行时,缓存了执行计划后,保存缓存的执行计划被第一次执行时构造的PlanState结构,并在之后的执行中重用保存下来的PlanState,只对结构中部分成员值重新赋值,避免每次执行时重新构造PlanState造成的时间的消耗。该方法通过对PostgreSQL预备语句执行进行优化,从而显著提高预备语句的执行效率。
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
本实施例提供了一种PostgreSQL预备语句执行优化方法,请参见图1,该方法包括:
S1:对执行过程中的相关数据结构进行调整,用以准备执行时需要用的信息,相关数据结构包括执行器状态内存上下文estate_context、全局指针变量、用于预备语句缓存计划的结构体缓存计划CachedPlan以及用于保存查询时需要使用的信息的结构体QueryDesc;
S2:对准备阶段的函数PortalStart进行改动,增加预备语句的判断以及计划是否被缓存的判断过程,其中,函数PortalStart用于根据不同的查询类型选择不同的操作,为执行查询准备一个门户;
S3:对函数standard_ExecutorStart进行改动,增加执行的是否为一个预备语句的判断以及执行器的状态是否被缓存的判断过程,standard_ExecutorStart函数用于准备一个执行计划;
S4:基于S1得到的数据结构、S2得到的PortalStart函数、S3得到的standard_ExecutorStart函数对预备语句进行执行;
S5:在预备语句执行之后,通过修改函数PortalCleanup,使得清理过程中,跳过函数ExecutorEnd对estate,planstate和ExecutorState上下文的清理,创建内存上下文estate_context用以保存ExecutorState上下文,其中,函数PortalCleanup为用于门户清理的函数,estate为执行器调用时的工作状态信息,planstate为计划的状态信息、ExecutorState上下文为执行器状态上下文。
总体来说,本发明是通过在执行预备语句时,保存第一次执行构造的PlanState结构,并在之后的执行中重用保存下来的PlanState,只需对结构中部分成员值重新赋值,从而提高预备语句的执行效率。
在PostgreSQL中,有以下三种预备语句的执行方式:
1.SQL语句执行方式
2.以前/后端协议方式执行PBE
3.服务器端编程接口SPI执行预备语句
本发明的方法对三种预备语句执行方式都通用。
SQL语句完整执行过程通常包含解析,优化和执行。而预备语句只需在第一次执行时对查询语句进行解析和优化,然后将得到的执行计划缓存下来,之后每次执行时省去解析和优化工作,找到缓存的执行计划重用即可。但在执行这一步骤中,又主要分为PortalStart,PortalRun和PortalDrop三个阶段,函数PortalStart用来准备执行时需要用到的各种信息,PortalRun使用PortalStart准备的信息进行具体的执行过程,得到结果并返回,PortalDrop是在执行阶段完成后,进行相关信息的清理工作。本方案不需要改动执行阶段PortalRun,只需要在准备阶段PortalStart和清理阶段PortalDrop进行改动,(S1~S3对应PortalStart阶段,S4对应PortalRun阶段,S5对应PortalDrop阶段)
三个函数都涉及到的重要结构为Portal。Portal即门户,该结构体代表了查询执行时的状态信息,Portal及其下属成员分别放在PortalMemory和PortalHeapMemory两个内存上下文(MCXT)中,PortalMemory门户内存上下文是所有PortalHeapMemory内存上下文的父节点。PortalHeapMemory代表每个Portal专有的内存上下文,用来存放Portal下属成员内容。
EState结构体表示执行器调用时工作状态相关信息,包括执行中的快照,参数信息等。在PortalHeapMemory下面的ExecutorState执行器内存上下文中创建该类型变量。
PlanState结构体是计划状态信息,是一个与执行计划树平行的用来描述计划树相关信息的计划状态树,和执行计划树Plan作为所有Plan类型节点的公共抽象超类一样,PlanState是所有PlanState类型节点的公共抽象超类。例如,执行计划树有一个IndexScan索引扫描类型的节点,表示有索引扫描操作,则相应的PlanState树有一个IndexScanState索引扫描状态类型的节点,记录执行索引扫描时的相关信息。每次查询执行时的PlanState类型变量也在ExecutorState上下文中创建,因此,将ExecutorState内存上下文保存下来即可缓存EState和PlanState结构。
需要说明的是,本发明中除有特殊说明之外,所提及的大写开头EState和PlanState指结构体类型,小写estate和planstate分别是EState和PlanState类型的变量,也就是需要被缓存的内容。
在一种实施方式中,S1具体包括:
S1.1:添加新的内存上下文estate_context,作为TopMemoryContext的子节点,其中,TopMemoryContext为根内存上下文,是所有内存上下文节点的根节点,estate_context内存上下文作用是缓存需要重用的estate和planstate结构所在的内存上下文;
S1.2:添加两个全局变量estate_planstatecache和planstate_planstatecache,分别用于指向要保存的执行器调用时的工作状态信息estate和计划的状态信息planstate;
S1.3:在结构体缓存计划CachedPlan中添加三个成员:
bool is_generic;用于判断一个缓存计划是否为一个一般计划,
Estate*estate_psc;当一个缓存计划为一般计划时,用于保存需要重用的执行器调用时的工作状态信息estate;
PlanState*PlanState;当该cachedplan是一般计划时,用于保存需要重用的计划的状态信息planstate;
S1.4:在QueryDesc结构中添加三个成员:
bool isprep;用于判断一个执行的语句是否为一个prepare的语句;
Estate*estate_psc;用于指向需要重用的执行器调用时的工作状态信息estate;
PlanState*planstate_psc;用于指向需要重用计划的状态信息planstate。
具体来说,首先介绍一下PostgreSQL的内存管理机制,PostgreSQL的内存管理是通过内存上下文,是一个树形结构。TopMemoryContext是所有内存上下文的根节点,PortalMemory是TopMemoryContext的一个子节点,与estate_context是兄弟节点。而PortalHeapMemory是每个portal独有的内存上下文,作为PortalMemory的子节点。
S1.1中,增加了新的执行器状态内存上下文,用于保存需要重用的Estate结构的上下文环境。在具体实施过程中,在第一次执行预备语句后,不清理ExecutorState上下文,而是将其父节点从PortalMemory改为estate_context上下文。
S1.2中,两个全局指针变量用于在进行相关内存上下文清理工作前,分别指向需要缓存的estate和planstate,以便在之后重用时,通过指针指向的地址找到缓存下来的estate和planstate。
步骤1.3,CachedPlan缓存计划是预备语句缓存plan时需要使用的结构体,包含在缓存一个Plan时需要用到的相关信息。bool is_generic;用来判断该CachedPlan是否为一个一般计划,如果为true,说明plan计划树被缓存下来了,因此可以将该plan相应的planstate缓存下来重用。
EState*estate_psc;当该CachedPlan是一般计划时,用来保存需要重用的estate。
PlanState*planstate_psc;当该CachedPlan是一般计划时,用来保存需要重用的planstate。
S1.4中,QueryDesc结构体中添加三个成员:QueryDesc是查询器执行一个查询时需要使用的信息,作为Portal的成员之一。因为在后续创建estate和planstate的函数中,只传递了queryDesc(QueryDesc类型的变量),所以无法获取Portal成员cplan(CachedPlan类型的变量),因此需要在QueryDesc结构体中添加以下三个成员,其中estate_psc和planstate_psc分别用来指向cplan中的estate_psc和planstate_psc,达到在后续步骤传递缓存的变量的目的。
在一种实施方式中,S2具体包括:
在执行CreateQueryDesc创建queryDesc后,通过增加判断语句判断一个语句是否为预备语句,如果不是预备语句,则按照原PortalStart函数流程执行;如果是预备语句,则判断缓存计划是否为一个一般计划,若不是一般计划,则继续按原函数PortalStart流程执行;如果是一般计划,则将queryDesc的成员isprep设置为true,接着判断缓存计划cplan的estate_psc和planstate_psc是否存在,如果不存在则继续按原函数流程执行;如果存在,则将queryDesc的estate_psc和planstate_psc分别指向cplan中的estate_psc和planstate_psc,其中,cplan是一个CachedPlan类型的变量,表示一个缓存计划。
具体来说,PortalStart函数是根据不同的查询类型选择不同的操作,为执行查询准备一个portal,该函数作为执行一个SQL查询的入口函数,进行相应的准备工作,具体为portal中的各成员赋值。当portal->strategy为PORTAL_ONE_SELECT时,即预备语句是SELECT类型的查询,原PortalStart函数主要操作是先调用CreateQueryDesc创建一个queryDesc,接下来调用相关函数创建estate和planstate等。
因此,在PortalStart中,当portal->strategy为PORTAL_ONE_SELECT,即策略为执行SELECT查询语句时,添加一些判断的语句。
具体实施过程中,通过if语句判断portal->cplan是否存在,如果不存在说明不是执行prepare语句(预备语句),其中,cplan是一个CachedPlan类型的变量,该变量只有在执行预备语句时才可能有值。cplan如果存在,即该变量不为NULL,说明存在一个缓存下来的执行计划。如果不存在则为NULL,说明没有被缓存的执行计划,同时也说明不可能为执行prepare语句。
根据cplan->is_generic判断cplan是否为一个generic plan(一般计划),若不是则说明计划没有被缓存,因此也不需要缓存planstate。在判断cplan的estate_psc和planstate_psc不存在时,说明是第一次执行一个generic plan,需要重用的estate和planstate还没有被保存下来,继续按原函数流程走;如果存在则将queryDesc的estate_psc和planstate_psc分别指向cplan中的estate_psc和planstate_psc。
在一种实施方式中,S3具体包括:
在PortalStart函数中创建queryDesc后,接下来调用函数ExecutorStart,ExecutorStart的执行中调用函数standard_ExecutorStart,函数standard_ExecutorStart用于准备一个执行计划,即创建estate和planstate;
在函数standard_ExecutorStart中更改创建estate的步骤;通过增加一个判断语句判断queryDesc->isprep是否为一个预备语句以及queryDesc中的estate_psc是否存在,如果都存在,则将estate指向estate_psc;
否则按正常流程执行创建estate,并且判断如果isprep为true则将全局变量estate_planstatecache指向创建的estate;
切换内存上下文到estate下的es_query_cxt,es_query_cxt为ExcutorState内存上下文,表示在代码中estate的成员变量,然后重新设置部分estate中会变化的字段值,字段值包括:estate的参数列表es_param_list_info,每次都需要根据的执行语句的参数重新绑定。
具体来说,ExecutorStart是PostgreSQL中用来设置hook机制的一个函数,利用全局的函数指针ExecutorStart_hook,用户可以实现自己想要实现的执行器预备功能。ExecutorStart_hook初始为NULL,如果指针有指向的函数,则调用指向的函数;否则调用PostgreSQL中标准的standard_ExecutorStart函数,用于准备一个执行计划。
在PortalStart函数中创建queryDesc后,接下来调用ExecutorStart,ExecutorStart中调用函数standard_ExecutorStart,该函数用于准备一个执行计划,即创建estate和planstate。其中调用函数CreateExecutorState创建estate,之后调用InitPlan创建planstate。standard_ExecutorStart函数修改前,首先会创建estate。
具体实施过程中,通过用if语句判断queryDesc->isprep是否为true(为true说明本次执行的是一个预备语句)以及queryDesc->estate_psc是否存在(若存在则说明estate已经被缓存下来),如果都为true则将estate指向estate_psc,这时就获取到了缓存的estate;否则进入else分支按原函数流程执行,使用函数CreateExecutorState创建新的estate,并且判断如果isprep为true则说明为是第一次执行该预备语句,相应的estate还未被缓存。如果为执行预备语句,则将全局变量estate_planstatecache指向创建的estate,方便后续步骤获取该estate。
在判断过程执行结束后,则切换内存上下文到estate下的es_query_cxt。
S3中的相关伪代码如下:
if…else条件判断:if(queryDesc->isprep&&queryDesc->estate_psc)
获取缓存的estate;
else
调用CreateExecutorState创建新的estate;
如果是执行预备语句,将estate_planstatecache指向estate。
在一种实施方式中,在函数standard_ExecutorStart中,除了创建estate,还会调用InitPlan函数创建planstate,在InitPlan函数中,调用ExecInitNode先为子计划生成相应的planstate,然后为plan创建相应的planstate,在步骤S3之后,所述方法还包括:
在执行InitPlan时,更改ExecInitNode创建PlanState的步骤,首先判断queryDesc->isprep是否为一个预备语句以及queryDesc中的planstate_psc是否存在,如果都为真则将PlanState指向planstate_psc,并调用函数ResetPlanState对保存下来的estate和planstate进行部分成员值的重置;否则执行ExecInitNode创建一个PlanState,并再次判断如果isprep为真则将全局变量planstate_planstatecache指向创建的planstate。
具体来说,在执行InitPlan时,更改创建planstate的步骤,加入可以重用缓存的planstate代码。步骤如下:定义planstate变量,首先if判断queryDesc->isprep是否为true以及queryDesc->planstate_psc是否存在,如果都为true则将planstate指向planstate_psc,即指向缓存的planstate,然后并调用函数ResetPlanState(该函数用来对planstate的每个类型的节点,根据本次预备语句执行的参数信息,快照信息等重新部分成员值设置)对保存下来的estate和planstate进行部分成员值的重置;否则进入else分支按照原步骤执行ExecInitNode创建一个新的planstate,并再次判断如果isprep为true则将全局变量planstate_planstatecache指向创建的planstate,方便后续步骤获取该planstate。
在一种实施方式中,所述方法还包括:添加函数ResetPlanState:
函数声明为:VoidResetPlanState(PlanState*node,Estate*estate);
在InitPlan中,执行预备语句如果存在保存下来的planstate,在将当前的planstate指向保存下来的planstate,然后执行ResetPlanState重新设置planstate和estate中需要更新的成员,ResetPlanState函数用于根据node类型执行不同的重置操作;
遍历PlanState tree的每个节点,设置planstate和estate中每次执行会变化的字段值,当所有需要改变的字段值设置完成后,继续调用PortalRun函数,其中,PortalRun函数为门户执行函数,用来在PortalStart函数完成所有相关信息准备工作后,执行查询,获取并返回查询语句的执行结果。
在一种实施方式中,函数PortalDrop是进行Portal清理的入口函数,其中通过portal->cleanup函数指针指向PortalCleanup,PortalCleanup函数是进行Portal清理工作的函数之一,对Portal的成员queryDesc及queryDesc下的estate和planstate内容进行清理,S5具体包括:
S5.1:判断portal->cplan是否存在,若不存在说明不是执行预备语句,直接按原步骤执行函数ExecutorEnd;若存在则说明是执行预备语句,然后判断是否存在estate_context内存上下文,不存在则创建,函数ExecutorEnd用于在执行完SQL之后进行清理工作;
S5.2:根据queryDesc->isprep和cplan->is_generic判断是否为一个一般计划,若不是则执行函数ExecutorEnd;若是,则当portal->strategy为PORTAL_ONE_SELECT且estate和planstate还未被缓存,则保存需要重用的estate和planstate,同时将相应的estate的内存上下文es_query_cxt的父节点设置为estate_context。
具体来说,函数PortalDrop是进行Portal清理的入口函数,其中通过portal->cleanup函数指针指向PortalCleanup。PortalCleanup函数是进行Portal清理工作的函数之一,对Portal的成员queryDesc及queryDesc下的estate和planstate等内容进行清理。每次执行完一个查询后PortalCleanup中会调用ExecutorEnd函数对estate的内存上下文es_query_cxt进行具体的清理,这样会将estate和planstate的内容全部一起清理。因此需要更改PortalCleanup函数,从而避免每次执行完都把estate和planstate清理掉。
ExecutorEnd函数主要作用是完成执行完SQL之后的清理工作,具体是将estate和planstate的内容清理掉,最后对estate的内存上下文es_query_cxt进行释放。
现有的方法,一个预备语句被多次执行,每次在PortalStart函数进行执行的相关信息准备时,都要重新创建estate和planstate。使用以上步骤之后,一个预备语句多次执行时,即可以跳过使用函数CreateExecutorState创建estate和使用函数ExecInitNode创建planstate的过程,而是获取被缓存下来的estate和planstate所在的内存上下文ExecutorState,然后切换到该内存上下文得到被缓存的estate和planstate变量,接着调用函数ResetPlanState对两个变量中部分值的进行重新设置,完成PortalStart步骤,然后后续的执行过程PortalRun即可使用缓存的estate和planstate,得到正确的结果。最后的PortalDrop清理,跳过函数ExecutorEnd对estate,planstate和ExecutorState上下文的清理,创建内存上下文estate_context用来保存ExecutorState上下文,这样就把estate和planstate缓存下来了。
下面通过一个具体的示例对本发明提出的方法进行进一步说明:
本发明是通过在执行预备语句时,保存第一次执行构造的PlanState结构,并在之后的执行中重用保存下来的PlanState,只需对结构中部分成员值重新赋值,从而提高预备语句的执行效率。现采用一个具体实例进行详细说明:
CREATE TABLE test(a int,b int);a上有哈希索引
使用SQL语句执行方式的预备语句。
预备语句:PREPARE s SELECT*FROM testWHERE a=$1andb<10;
使用随机的参数多次执行该预备语句:EXECUTE s(1);EXECUTE s(2);EXECUTE s(3);EXECUTE s(1);EXECUTE s(4);EXECUTE s(7);EXECUTE s(10);……
在查询编译时,对于原代码,该预备语句会被解析以名称s保存下来,每次在执行时会获取代入的参数。获取执行计划时,会通过相应的方法判断是重新生成计划树还是使用缓存下的计划树。该计划树包括Hash节点,IndexScan节点和SeqScan节点三个节点(Hash节点表示哈希节点,在有哈希操作时需要使用;IndexScan是索引扫描节点,用于索引扫描;SeqScan是顺序扫描节点,需要执行顺序扫描时使用),未进行优化之前,在函数InitPlan中,无论是重新生成的执行计划还是之前缓存的执行计划,都需要根据先前获取的plan树创建一个对应的新的planstate树结构,该结构同样有以上三种节点类型,分别为HashState,IndexScanState和SeqScanState(HashState节点表示哈希状态节点,对应在执行中有Hash节点时需要用于描述哈希操作的相关信息;IndexScanState是索引扫描状态节点,用于索引扫描节点执行时描述相关信息;SeqScan是顺序扫描状态节点,用于顺序扫描节点执行时描述相关信息)。在每次执行完PortalRun后,PortalDrop函数进行Portal的清理操作,包括清理相应的内存上下文,会将estate和planstate等结构一并清除。
但是通过使用该发明,在查询编译时,如果计划树被缓存了下来,只需要在第一次执行该缓存的计划时生成相应的planstate,PortalDrop不会清理的planstate所在的ExcutorState内存上下文,而是创建一个以TopMemoryContext为父节点的内存上下文estate_context。接下来将ExcutorState内存上下文的父节点从TopMemoryContext改为指向estate_context,从而也将相应的estate和planstate保存下来。
在之后该预备语句的执行中,不再创建新的estate和ExcutorState内存上下文,而是将内存上下文切换到estate_context下的ExcutorState内存上下文,并获取其中的estate和planstate。即将本次执行时的estate和planstate分别指向Portal下的queryDesc中的成员estate_psc和planstate_psc。执行InitPlan时,不再执行ExecInitNode创建新的planstate,而是使用之前保存的planstate,即planstate_psc,该planstate树同样具有HashState,IndexScanState和SeqScanState三个节点。此时执行的内存上下文为保存下来的ExecutorState,也获取了保存下来重用的estate和planstate结构。然后调用函数ResetPlanState,将estate和planstate作为函数ResetPlanState的参数,该函数的功能即重新设置estate和planstate中三个节点的部分成员值。
每次完成成员值重设后,即可使用该planstate执行PortalRun。这样节省了每次重新创建planstate的大量时间。
对于其他具有不同planstate节点类型的查询,情况类似,执行过程只需对不同planstate节点的成员值进行不同处理。
应当具体说明的是:本发明具有以下主要有益效果:
第一.本发明中提出的预备语句执行优化方案,对于预备语句的查询执行效率有很大的提升作用,具体说明如下:
针对预备语句执行,对于任何复杂的查询,在首次执行被缓存下的执行计划时生成的PlanState结构,将其保存下来,之后该预备语句的执行都可以反复使用该PlanState,只改变其中部分成员值,而无需重新创建。从而节省了每次执行该预备语句时重新创建PlanState的时间开销,对预备语句的执行效率有明显提升作用。
第二.本发明中提出的预备语句执行优化方案,对于系统实现有较大的指导作用,具体说明如下:
预备语句编译执行时,会缓存执行计划从而反复使用节省时间开销,并且计划树和PlanState树的节点是一一对应关系的这一特点,所以采用类似缓存执行计划的方式,将PlanState缓存下来,然后在之后的执行中反复使用,为预备语句编译执行提供了一种高效的改进方法。
本发明中所描述的具体实施例仅仅是对本发明精神作举例说明。本发明所属技术领域的技术人员可以对所描述的具体实施例做各种的修改或补充或采用类似的方式替代,但并不会偏离本发明的精神或者超越所附权利要求书所定义的范围。
Claims (6)
1.一种PostgreSQL预备语句执行优化方法,其特征在于,包括:
S1:对执行过程中的相关数据结构进行调整,用以准备执行时需要用的信息,相关数据结构包括执行器状态内存上下文estate_context、全局指针变量、用于预备语句缓存计划的结构体缓存计划CachedPlan以及用于保存查询时需要使用的信息的结构体QueryDesc;
S2:对准备阶段的函数PortalStart进行改动,增加预备语句的判断以及计划是否被缓存的判断过程,其中,函数PortalStart用于根据不同的查询类型选择不同的操作,为执行查询准备一个门户;
S3:对函数standard_ExecutorStart进行改动,增加执行的是否为一个预备语句的判断以及执行器的状态是否被缓存的判断过程,standard_ExecutorStart函数用于准备一个执行计划;
S4:基于S1得到的数据结构、S2得到的PortalStart函数、S3得到的standard_ExecutorStart函数对预备语句进行执行;
S5:在预备语句执行之后,通过修改函数PortalCleanup,使得清理过程中,跳过函数ExecutorEnd对estate,planstate和ExecutorState上下文的清理,创建内存上下文estate_context用以保存ExecutorState上下文,其中,函数PortalCleanup为用于门户清理的函数,estate为执行器调用时的工作状态信息,planstate为计划的状态信息、ExecutorState上下文为执行器状态上下文;
其中,S3具体包括:
在PortalStart函数中创建queryDesc后,接下来调用函数ExecutorStart,ExecutorStart的执行中调用函数standard_ExecutorStart,函数standard_ExecutorStart用于准备一个执行计划,即创建estate和planstate;
在函数standard_ExecutorStart中更改创建estate的步骤;通过增加一个判断语句判断queryDesc->isprep是否为一个预备语句以及queryDesc中的estate_psc是否存在,如果都存在,则将estate指向estate_psc;
否则按正常流程执行创建estate,并且判断如果isprep为true则将全局变量estate_planstatecache指向创建的estate;
切换内存上下文到estate下的es_query_cxt,es_query_cxt为ExcutorState内存上下文,表示在代码中estate的成员变量,然后重新设置部分estate中会变化的字段值,字段值包括:estate的参数列表es_param_list_info,每次都需要根据的执行语句的参数重新绑定。
2.如权利要求1所述的优化方法,其特征在于,S1具体包括:
S1.1:添加新的内存上下文estate_context,作为TopMemoryContext的子节点,其中,TopMemoryContext为根内存上下文,是所有内存上下文节点的根节点,estate_context内存上下文作用是缓存需要重用的estate和planstate结构所在的内存上下文;
S1.2:添加两个全局变量estate_planstatecache和planstate_planstatecache,分别用于指向要保存的执行器调用时的工作状态信息estate和计划的状态信息planstate;
S1.3:在结构体缓存计划CachedPlan中添加三个成员:
bool is_generic;用于判断一个缓存计划是否为一个一般计划,
Estate*estate_psc;当一个缓存计划为一般计划时,用于保存需要重用的执行器调用时的工作状态信息estate;
PlanState*PlanState;当一个缓存计划为一般计划时,用于保存需要重用的计划的状态信息planstate;
S1.4:在QueryDesc结构中添加三个成员:
bool isprep;用于判断一个执行的语句是否为一个prepare的语句;
Estate*estate_psc;用于指向需要重用的执行器调用时的工作状态信息estate;
PlanState*planstate_psc;用于指向需要重用计划的状态信息planstate。
3.如权利要求1所述的优化方法,其特征在于,S2具体包括:
在执行CreateQueryDesc创建queryDesc后,通过增加判断语句判断一个语句是否为预备语句,如果不是预备语句,则按照原PortalStart函数流程执行;如果是预备语句,则判断缓存计划是否为一个一般计划,若不是一般计划,则继续按原函数PortalStart流程执行;如果是一般计划,则将queryDesc的成员isprep设置为true,接着判断缓存计划cplan的estate_psc和planstate_psc是否存在,如果不存在则继续按原函数流程执行;如果存在,则将queryDesc的estate_psc和planstate_psc分别指向cplan中的estate_psc和planstate_psc,其中,cplan是一个CachedPlan类型的变量,表示一个缓存计划。
4.如权利要求1所述的优化方法,其特征在于,在函数standard_ExecutorStart中,除了创建estate,还会调用InitPlan函数创建planstate,在InitPlan函数中,调用ExecInitNode先为子计划生成相应的planstate,然后为plan创建相应的planstate,在步骤S3之后,所述方法还包括:
在执行InitPlan时,更改ExecInitNode创建PlanState的步骤,首先判断queryDesc->isprep是否为一个预备语句以及queryDesc中的planstate_psc是否存在,如果都为真则将PlanState指向planstate_psc,并调用函数ResetPlanState对保存下来的estate和planstate进行部分成员值的重置;否则执行ExecInitNode创建一个PlanState,并再次判断如果isprep为真则将全局变量planstate_planstatecache指向创建的planstate。
5.如权利要求4所述的优化方法,其特征在于,所述方法还包括:添加函数ResetPlanState:
函数声明为:Void ResetPlanState(PlanState*node,Estate*estate);
在InitPlan中,执行预备语句如果存在保存下来的planstate,在将当前的planstate指向保存下来的planstate,然后执行ResetPlanState重新设置planstate和estate中需要更新的成员,ResetPlanState函数用于根据node类型执行不同的重置操作;
遍历PlanState tree的每个节点,设置planstate和estate中每次执行会变化的字段值,当所有需要改变的字段值设置完成后,继续调用PortalRun函数,其中,PortalRun函数为门户执行函数,用来在PortalStart函数完成所有相关信息准备工作后,执行查询,获取并返回查询语句的执行结果。
6.如权利要求1所述的优化方法,其特征在于,函数PortalDrop是进行Portal清理的入口函数,其中通过portal->cleanup函数指针指向PortalCleanup,PortalCleanup函数是进行Portal清理工作的函数之一,对Portal的成员queryDesc及queryDesc下的estate和planstate内容进行清理,S5具体包括:
S5.1:判断portal->cplan是否存在,若不存在说明不是执行预备语句,直接按原步骤执行函数ExecutorEnd;若存在则说明是执行预备语句,然后判断是否存在estate_context内存上下文,不存在则创建,函数ExecutorEnd用于在执行完SQL之后进行清理工作;
S5.2:根据queryDesc->isprep和cplan->is_generic判断是否为一个一般计划,若不是则执行函数ExecutorEnd;若是,则当portal->strategy为PORTAL_ONE_SELECT且estate和planstate还未被缓存,则保存需要重用的estate和planstate,同时将相应的estate的内存上下文es_query_cxt的父节点设置为estate_context。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202010503294.5A CN111797112B (zh) | 2020-06-05 | 2020-06-05 | 一种PostgreSQL预备语句执行优化方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202010503294.5A CN111797112B (zh) | 2020-06-05 | 2020-06-05 | 一种PostgreSQL预备语句执行优化方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN111797112A CN111797112A (zh) | 2020-10-20 |
CN111797112B true CN111797112B (zh) | 2022-04-01 |
Family
ID=72802846
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202010503294.5A Expired - Fee Related CN111797112B (zh) | 2020-06-05 | 2020-06-05 | 一种PostgreSQL预备语句执行优化方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN111797112B (zh) |
Citations (10)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5903893A (en) * | 1997-09-15 | 1999-05-11 | International Business Machines Corporation | Method and apparatus for optimizing a merge-join operation across heterogeneous databases |
US6006220A (en) * | 1997-09-30 | 1999-12-21 | International Business Machines Corporation | Determining the optimal access path for a query at execution time using an actual value for each variable in a query for estimating a filter factor |
CN102393842A (zh) * | 2011-06-28 | 2012-03-28 | 用友软件股份有限公司 | 指令处理装置和指令处理方法 |
CN102521409A (zh) * | 2011-12-28 | 2012-06-27 | 北京人大金仓信息技术股份有限公司 | 一种基于通信协议的数据库数据批量更新方法 |
CN105653647A (zh) * | 2015-12-28 | 2016-06-08 | 中国联合网络通信集团有限公司 | Sql语句的信息采集方法及系统 |
CN106897343A (zh) * | 2016-07-20 | 2017-06-27 | 阿里巴巴集团控股有限公司 | 执行计划的查找方法、存储方法及装置 |
CN107463635A (zh) * | 2016-09-21 | 2017-12-12 | 广州特道信息科技有限公司 | 一种图片数据查询的方法和分布式NewSQL数据库系统 |
CN108197306A (zh) * | 2018-01-30 | 2018-06-22 | 平安科技(深圳)有限公司 | Sql语句处理方法、装置、计算机设备和存储介质 |
CN109918389A (zh) * | 2019-03-13 | 2019-06-21 | 试金石信用服务有限公司 | 基于消息流和图数据库的数据风控方法、装置及存储介质 |
CN110399377A (zh) * | 2019-08-30 | 2019-11-01 | 北京东软望海科技有限公司 | Sql的优化方法、装置、电子设备及计算机可读存储介质 |
Family Cites Families (10)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CA2249066C (en) * | 1998-09-29 | 2001-12-04 | Ibm Canada Limited-Ibm Canada Limitee | Sharing of dynamic sql statements in a heterogeneous application environment |
CA2249096C (en) * | 1998-09-30 | 2001-12-04 | Ibm Canada Limited-Ibm Canada Limitee | Method for determining optimal database materializations using a query optimizer |
CA2366192A1 (en) * | 2001-12-21 | 2003-06-21 | Ibm Canada Limited-Ibm Canada Limitee | Organization of sql working memory in a transaction bounded processing environment |
CA2382714A1 (en) * | 2002-04-19 | 2003-10-19 | Ibm Canada Limited-Ibm Canada Limitee | Substituting parameter markers for literals in a database query language statement to promote reuse of previously generated access plans |
US20070112781A1 (en) * | 2005-11-17 | 2007-05-17 | Mcmullen Cindy | System and method for providing search controls in a communities framework |
CN104714984A (zh) * | 2013-12-17 | 2015-06-17 | 中国移动通信集团湖南有限公司 | 一种数据库优化的方法和装置 |
CN106407246B (zh) * | 2016-07-22 | 2020-12-04 | 平安科技(深圳)有限公司 | Sql执行计划管理的方法及装置 |
CN106599130B (zh) * | 2016-12-02 | 2020-05-01 | 中国银联股份有限公司 | 选择干预关系型数据库管理系统的多个索引的方法及装置 |
CN110633290A (zh) * | 2018-06-20 | 2019-12-31 | 苏宁易购集团股份有限公司 | 一种sql语句分析方法及分析装置 |
CN110019349A (zh) * | 2019-04-02 | 2019-07-16 | 深圳前海微众银行股份有限公司 | 语句预警方法、装置、设备及计算机可读存储介质 |
-
2020
- 2020-06-05 CN CN202010503294.5A patent/CN111797112B/zh not_active Expired - Fee Related
Patent Citations (10)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5903893A (en) * | 1997-09-15 | 1999-05-11 | International Business Machines Corporation | Method and apparatus for optimizing a merge-join operation across heterogeneous databases |
US6006220A (en) * | 1997-09-30 | 1999-12-21 | International Business Machines Corporation | Determining the optimal access path for a query at execution time using an actual value for each variable in a query for estimating a filter factor |
CN102393842A (zh) * | 2011-06-28 | 2012-03-28 | 用友软件股份有限公司 | 指令处理装置和指令处理方法 |
CN102521409A (zh) * | 2011-12-28 | 2012-06-27 | 北京人大金仓信息技术股份有限公司 | 一种基于通信协议的数据库数据批量更新方法 |
CN105653647A (zh) * | 2015-12-28 | 2016-06-08 | 中国联合网络通信集团有限公司 | Sql语句的信息采集方法及系统 |
CN106897343A (zh) * | 2016-07-20 | 2017-06-27 | 阿里巴巴集团控股有限公司 | 执行计划的查找方法、存储方法及装置 |
CN107463635A (zh) * | 2016-09-21 | 2017-12-12 | 广州特道信息科技有限公司 | 一种图片数据查询的方法和分布式NewSQL数据库系统 |
CN108197306A (zh) * | 2018-01-30 | 2018-06-22 | 平安科技(深圳)有限公司 | Sql语句处理方法、装置、计算机设备和存储介质 |
CN109918389A (zh) * | 2019-03-13 | 2019-06-21 | 试金石信用服务有限公司 | 基于消息流和图数据库的数据风控方法、装置及存储介质 |
CN110399377A (zh) * | 2019-08-30 | 2019-11-01 | 北京东软望海科技有限公司 | Sql的优化方法、装置、电子设备及计算机可读存储介质 |
Non-Patent Citations (1)
Title |
---|
"关于PostgreSQL的简单查询和扩展查询协议";skykiker;《http://blog.chinaunix.net/uid-20726500-id-4761997.html》;20150115;第1-5页 * |
Also Published As
Publication number | Publication date |
---|---|
CN111797112A (zh) | 2020-10-20 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN112650766B (zh) | 数据库数据操作的方法、系统及服务器 | |
Weise et al. | Value dependence graphs: Representation without taxation | |
JP2811990B2 (ja) | プログラム処理装置及びプログラム処理方法 | |
US7324985B2 (en) | Methods and systems for database statement execution plan optimization | |
US11288268B2 (en) | Processing a user database query | |
US20080028380A1 (en) | Localized, incremental single static assignment update | |
CN112988782B (zh) | Hive支持交互式查询的方法、装置及存储介质 | |
CN110851142A (zh) | 一种将Transact-SQL程序转换为Java程序的方法 | |
CN113204571B (zh) | 涉及写入操作的sql执行方法、装置及存储介质 | |
CN111797112B (zh) | 一种PostgreSQL预备语句执行优化方法 | |
CN115794874A (zh) | 一种异构数据库系统中加速gpu算子执行的方法及应用 | |
CN110990001A (zh) | Ivr流程执行方法及装置 | |
CN108897569A (zh) | iOS工程无用文件的清理方法及计算机可读存储介质 | |
CN115114325B (zh) | 数据查询方法、装置、电子设备以及存储介质 | |
Rietveld et al. | Reducing layered database applications to their essence through vertical integration | |
WO2023121904A1 (en) | Processing a user query | |
CN104731695A (zh) | 一种支持表格驱动底层输入的单元测试系统和方法 | |
CN113296809A (zh) | 一种声明式的通用Kubernetes调谐方法 | |
CN113485710A (zh) | 一种低代码脚本实现方法及终端 | |
JP3714201B2 (ja) | コール命令並び替え方法と装置並びにプログラム | |
JPH0667871A (ja) | プログラム自動更新方式 | |
CN116627983A (zh) | 一种基于哈希连接的倾斜数据处理方法及相关设备 | |
JP2820184B2 (ja) | ロードモジュール単体テスト支援装置 | |
CN112597442A (zh) | 一种基于分布式的电力结算计算方法和系统 | |
CN113849412A (zh) | 一种车辆电子自动化测试方法、装置、系统和介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant | ||
CF01 | Termination of patent right due to non-payment of annual fee |
Granted publication date: 20220401 |