返回首页

gbase数据、南大通用产品文档:GBase8a:2181,1921686179:2181,1921686180:2181 topic oggtopic

更新日期:2024年09月11日

{"table":"BDTEST.GTEST","op_type":"I","op_ts":"2017-01-24 07:17:44.000209","current_ts":"2017
-01-24T15:17:47.504000","pos":"00000000010000001632","primary_keys":["A"],"after":{"A":"5","B"
:"5"}},

MOT 使您可以在执行之前以原生格式(使用PREPARE 语句)准备并分析预编译的完
整查询。
这种本机格式以后可以更有效地执行(使用EXECUTE 命令)

这种类型的执行效率要
高得多,因为在执行期间,
本机格式绕过了多个数据库处理层。
这种分工避免了重复的解析
分析操作。Lite Executor 模块负责执行预准备查询,其执行路径比封装执行的常规通用计划
要快得多。这是通过LLVM 使用实时(JIT)编译来实现的。此外,以伪LLVM 的形式提供
具有潜在相似性能的类似解决方案。
下面是SQL 中的PREPARE 语法示例:
PREPARE name [ ( data_type [, ...] ) ] AS statement
下面是一个如何在Java 应用程序中调用PREPARE 和EXECUTE 语句的示例:
conn = DriverManager.getConnection(connectionUrl, connectionUser, connectionPassword);
// Example 1: PREPARE without bind settings
String query = "SELECT * FROM getusers";
PreparedStatement prepStmt1 = conn.prepareStatement(query);

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
502
ResultSet rs1 = pstatement.executeQuery())
while (rs1.next()) {…}
// Example 2: PREPARE with bind settings
String sqlStmt = "SELECT * FROM employees where first_name=? and last_name like ?";
PreparedStatement prepStmt2 = conn.prepareStatement(sqlStmt);
prepStmt2.setString(1, "Mark"); // first name “Mark”
prepStmt2.setString(2, "%n%"); // last name contains a letter “n”
ResultSet rs2 = prepStmt2.executeQuery())
while (rs2.next()) {…}
Prepare
Prepare 创建一个预处理语句。预处理语句是服务器端对象,可用于优化性能。执行
PREPARE 语句时,将解析、分析和重写指定的语句。
如果查询语句中提到的表是MOT 表,则MOT 编译负责对象准备,并基于LLVM 将查
询编译成IR 字节码进行特殊优化。
每当需要新的查询编译时,都会分析查询,并使用实用程序GsCodeGen 对象和标准
LLVM JIT API(IRBuilder)为查询生成合适的IR 字节代码。完成字节代码生成后,代码将
被JIT 编译到单独的LLVM 模块中。编译的代码生成一个C 函数指针,以后可以调用该指
针直接执行。请注意,这个C 函数可以被许多线程并发调用,只要每个线程提供不同的执
行上下文(详细信息如下)。每个这样的执行上下文称为“JIT 上下文”。
为了进一步提高性能,MOT JIT 对其LLVM 代码结果应用缓存策略,使它们能够被在
不同会话中的相同查询重用。
执行
当发出EXECUTE 命令时,会计划并执行预准备语句(上文所述)。这种分工避免了重
复的解析分析工作,同时使执行计划依赖于提供的特定设置值。
当生成的执行查询命令到达数据库时,它使用相应的IR 字节代码,在MOT 引擎中直
接执行该代码,并且执行效率更高。这称为“轻量级执行”。
此外,为了可用性,Lite Executor 维护了一个预先分配的JIT 源池。每个会话预分配自
己的会话本地JIT 上下文对象池(用于重复执行预编译查询)。
JIT 编译对比-GBase 8c 盘表与MOT 表
目前,GBase 8c 包含针对其基于磁盘的表的JIT/CodeGen 查询优化的两种主要形式:

加速表达式计算,例如在WHERE 子句、目标列表、聚合和投影中。

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
503

内联小函数调用。
这些优化是局部的
(从某种意义上说,
它们不优化整个解释的运算符树或完全替换它)

并且主要针对CPU 绑定的复杂查询,通常在OLAP 用例中可见。查询的执行是在使用解释
运算符树的拉模型(Volcano 样式处理)中执行的。激活后,每次执行查询时都会执行编译。
目前,尚未提供生成的LLVM 代码的缓存及其跨会话和查询的重用。
相反,MOT JIT 优化为符合MOT JIT 优化条件的整个查询提供了LLVM 代码。结果代
码用于直接执行MOT 表,而解释的运算符模型则完全放弃。结果实际上是为整个特定查询
执行生成的手写LLVM 代码。
另一个显着的概念差异是MOT LLVM 代码只在查询的PREPARE阶段为准备查询生成,
而不是在查询执行时生成。由于OLTP 查询的运行时间相当短,因此这对于OLTP 场景尤其
重要,这无法在每次查询执行期间生成代码和执行较长的查询编译时间。
最后,在GBase 8c 中,激活PREPARE 意味着于同一个会话中具有不同参数的执行之
间重用生成的计划。同样,MOT JIT 对其LLVM 代码结果应用了缓存策略,并扩展了缓存
策略,以便在不同会话之间重用。因此,单个查询可以只编译一次,其LLVM 代码可以在
多个会话中重用,这同样有利于OLTP 场景。

持久性是指长期的数据保护(也称为磁盘持久性)
。持久性意味着存储的数据不会遭受
任何形式的退化或破坏,
因此数据不会丢失或损坏。
持久性可确保在有计划停机
(例如维护)
或计划外崩溃(例如电源故障)后数据和MOT 引擎恢复到一致状态。
内存存储是易失的,
需要电源来维护所存储的信息。
另一方面,
磁盘存储是非易失性的,
这意味着它不需要电源来维护存储的信息,因此它不用担心停电。MOT 使用这两种类型的
存储,
它拥有内存中的所有数据,
同时将事务性更改持久化到磁盘,
并保持频繁的定期MOT
检查点,以确保在关机时恢复数据。
用户必须保证有足够的磁盘空间用于日志记录和检查点操作。
检查点使用单独的驱动器,
通过减少磁盘I/O 负载来提高性能。

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
493
有关如何在MOT 引擎中实现持久性的概述,请参见MOT 关键技术。
MOT 的WAL 重做日志和检查点启用了持久性,如下所述。