预处理查询(PREPARED STATEMENT)的用途是用于高效地重复执行相同(或相似)SQL 语句,避免重复解析和构建计划。
set enable_optimizer=1;
) 时才会生效。Select
查询语句。PREPARED STATEMENT的基本语法包括下面四个 SQL 语句:
CREATE [
PERMANENT]
PREPARED STATEMENT
说明
EXECUTE PREPARED STATEMENT
SHOW PREPARED STATEMENT
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 包括以下几个来源(根据优先级从高到低):
下面这个例子说明了上述的优先级关系。
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];