You need to enable JavaScript to run this app.
导航
预处理查询 PREPARED STATEMENT
最近更新时间:2024.08.05 17:53:48首次发布时间:2024.08.05 17:53:48

预处理查询(PREPARED STATEMENT)的用途是用于高效地重复执行相同(或相似)SQL 语句,避免重复解析和构建计划。

使用限制
  • ByteHouse 企业版 2.5 及以上版本支持此特性。
  • 功能需要在开启优化器(set enable_optimizer=1;) 时才会生效。
  • 预处理查询功能暂时只适用于Select查询语句。

基本语法

PREPARED STATEMENT的基本语法包括下面四个 SQL 语句:

  1. 创建预处理查询:CREATE [PERMANENT] PREPARED STATEMENT

说明

  • 在创建时使用持久化关键字PERMANENT,可以将PREPARED STATEMENT以文件的形式保存在磁盘中,在Server重新启动后仍然会自动将PREPARED STATEMENT构建的计划保存到内存中。
  • 如果在创建预处理查询时包含临时表(System中有些表是临时表,StorageID会改变),在Server重新启动时,将无法对持久化的文件重新解析成计划。
  1. 执行预处理查询:EXECUTE PREPARED STATEMENT
  2. 查询已创建的预处理查询:SHOW PREPARED STATEMENT
  3. 删除指定预处理查询:DROP PREPARED STATEMENT

说明

在执行删除时,如果目标是使用持久化关键字 PERMANENT的预处理查询,则会将持久化的文件删除掉。

用法举例

创建预处理查询

语法

-- 使用 PREPARE 语句定义查询模版
-- 强烈建议使用 PERMANENT
CREATE [PERMANENT] PREPARED STATEMENT [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster_name]
AS
select query with prepared_parameters;

示例

CREATE PERMANENT PREPARED STATEMENT prep1 AS
SELECT count() 
FROM (SELECT number FROM system.numbers LIMIT 10)
WHERE number < [literal_name: DataType]; 
-- literal_name,常量名
-- DataType,常量参数类型

-- 具体实例
CREATE PERMANENT PREPARED STATEMENT prep1 AS
SELECT count()
FROM (SELECT number FROM system.numbers LIMIT 10)
WHERE number < [i: UInt32];

图片

查询预处理查询

查看所有预处理查询

--查看所有PREPARED STATEMENT
SHOW PREPARED STATEMENTS;

图片

查看某个预处理查询的执行计划

--查看所有PREPARED STATEMENT
EXPLAIN PREPARED STATEMENT prepared_name;

图片

查看某个预处理查询的创建语句

--查看所有PREPARED STATEMENT
SHOW CREATE PREPARED STATEMENT prepared_name;

图片

执行预处理查询

语法

-- 使用 EXECUTE 语句执行查询模版,通过 USING 绑定 prepared params
EXECUTE PREPARED STATEMENT fooplan USING literal1 = value1, literal2 = value2, ...

示例

CREATE PERMANENT PREPARED STATEMENT prep1 AS
SELECT count()
FROM (SELECT number FROM system.numbers LIMIT 10)
WHERE number < [i: UInt32];

EXECUTE PREPARED STATEMENT prep1 USING i = 1;
EXECUTE PREPARED STATEMENT prep1 USING i = 5;
EXECUTE PREPARED STATEMENT prep1 USING foo = 'bar'; -- { serverError 4080 }
-- 类型不准确,系统会报错。

图片

设置项优先级

在执行 EXECUTE PREPARED STATEMENT 语句时,生效的 settings 包括以下几个来源(根据优先级从高到低):

  1. EXECUTE 语句的 setting;
  2. 对应的 PREPARE 语句的 setting;
  3. 当前 Session 中的 setting(通过命令行参数或 SET 语句设置,以及全局默认配置);

下面这个例子说明了上述的优先级关系。

SET iterative_optimizer_timeout=111111;

CREATE PERMANENT PREPARED STATEMENT prep2 AS
SELECT value FROM system.settings WHERE name = 'iterative_optimizer_timeout';

CREATE PERMANENT PREPARED STATEMENT prep3 AS
SELECT value FROM system.settings WHERE name = 'iterative_optimizer_timeout'
SETTINGS iterative_optimizer_timeout=333333;

SET iterative_optimizer_timeout=222222;

EXECUTE PREPARED STATEMENT prep2; -- 执行结果为 222222
EXECUTE PREPARED STATEMENT prep3; -- 执行结果为 333333
EXECUTE PREPARED STATEMENT prep3 SETTINGS iterative_optimizer_timeout=444444; -- 执行结果为 444444

注意

PREPARE STATEMENT 语句会使用预先构建的计划,因此 Parser/优化器相关的参数仅会在 CREATE PREPARED STATEMENT 语句中生效。

删除预处理查询

语法

-- 删除指定PREPARED STATEMENT
DROP PREPARED STATEMENT [IF EXISTS] name [ON CLUSTER cluster_name];

示例

图片