当前位置:网站首页>Use IN List Population in Your JDBC Application to Avoid Cursor Cache Contention Issues
Use IN List Population in Your JDBC Application to Avoid Cursor Cache Contention Issues
2022-07-31 12:09:00 【DebugUsery】
Few developers are aware of a problem,那就是在SQL中使用INmay be encountered when listing "cursor cache contention "或 "Execution plan cache contention "的问题.This problem is described in detail in a previous article,It can be summed up like this.
All of these are differentSQL查询,Need to have a strong plan cacheRDBMS(例如Db2、Oracle、SQL Server)中被解析/计划/Cached execution plans that may differ:
SELECT * FROM t WHERE id IN (?);
SELECT * FROM t WHERE id IN (?, ?);
SELECT * FROM t WHERE id IN (?, ?, ?);
SELECT * FROM t WHERE id IN (?, ?, ?, ?);
SELECT * FROM t WHERE id IN (?, ?, ?, ?, ?);
复制代码Although this is on the developer machine不是 问题,But it will be generated in production重大 问题.我见过这种情况,during peak loads,整个OracleInstances are paralyzed.虽然RDBMSSuppliers should strive to avoid serious problems that could result from this,But you can use us injOOQInvented a trick to fix it(Hibernate现在也有).
IN 列表填充
这个技巧非常简单.只要将你的IN 列表 "填充 "到最接近的2 的幂数,Then repeat the last value,直到结束:
SELECT * FROM t WHERE id IN (?); -- Left as it is
SELECT * FROM t WHERE id IN (?, ?); -- Left as it is
SELECT * FROM t WHERE id IN (?, ?, ?, ?); -- Padded 3 to 4
SELECT * FROM t WHERE id IN (?, ?, ?, ?); -- Left as it is
SELECT * FROM t WHERE id IN (?, ?, ?, ?, ?, ?, ?, ?); -- Padded 5 to 8
复制代码This is really a hack,There are better solutions to avoid this problem,包括使用数组或临时表,But your production system may be down,You need a quick fix.
从jOOQ 3.9(2016年底)开始,jOOQ已经支持IN The list fills for years,But with relatively new parsers and ParsingConnection ,You can now also in your nonjOOQsystem to any arbitrarySQLQueries apply this technique.这里有一个简单的例子:
// Any arbitrary JDBC Connection is wrapped by jOOQ here and replaced
// by a "ParsingConnection", which is also a JDBC Connection
DSLContext ctx = DSL.using(connection);
ctx.settings().setInListPadding(true);
Connection c = ctx.parsingConnection();
// Your remaining code is left untouched. It is unaware of jOOQ
for (int i = 0; i < 10; i++) {
try (PreparedStatement s = c.prepareStatement(
// This alone is reason enough to use jOOQ instead,
// but one step at a time :)
"select 1 from dual where 1 in (" +
IntStream.rangeClosed(0, i)
.mapToObj(x -> "?")
.collect(Collectors.joining(", ")) +
")")
) {
for (int j = 0; j <= i; j++)
s.setInt(j + 1, j + 1);
try (ResultSet rs = s.executeQuery()) {
while (rs.next())
System.out.println(rs.getInt(1));
}
}
}
复制代码The above example just builds and runs10a query of this form:
select 1 from dual where 1 in (?)
select 1 from dual where 1 in (?, ?)
select 1 from dual where 1 in (?, ?, ?)
select 1 from dual where 1 in (?, ?, ?, ?)
select 1 from dual where 1 in (?, ?, ?, ?, ?)
select 1 from dual where 1 in (?, ?, ?, ?, ?, ?)
select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?)
select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?)
select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?, ?)
select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
复制代码But that's not what is being executed.在DEBUG日志中,我们可以看到以下内容:
Translating from : select 1 from dual where 1 in (?)
Translating to : select 1 from dual where 1 in (?)
Translating from : select 1 from dual where 1 in (?, ?)
Translating to : select 1 from dual where 1 in (?, ?)
Translating from : select 1 from dual where 1 in (?, ?, ?)
Translating to : select 1 from dual where 1 in (?, ?, ?, ?)
Translating from : select 1 from dual where 1 in (?, ?, ?, ?)
Translating to : select 1 from dual where 1 in (?, ?, ?, ?)
Translating from : select 1 from dual where 1 in (?, ?, ?, ?, ?)
Translating to : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?)
Translating from : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?)
Translating to : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?)
Translating from : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?)
Translating to : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?)
Translating from : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?)
Translating to : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?)
Translating from : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?, ?)
Translating to : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Translating from : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Translating to : select 1 from dual where 1 in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
复制代码就这样,Our legacy application is ready to run in production again,You will have time to address this more thoroughly.
结论
虽然jOOQMainly an interiorDSL,用于在JavaWrite type-safe embedded in SQL,But you can also base on anyJDBCuse it in many other applications.上面的例子是使用ParsingConnection ,It can parse all yoursSQL语句,and translate them/Convert to anything else,Including other dialects.
边栏推荐
- 数据湖(十九):SQL API 读取Kafka数据实时写入Iceberg表
- 学习笔记 Golang 写入文件(io.WriteString、ioutil.WriteFile、file.Write、write.WriteString)
- 基于稳态视觉诱发电位和注意力脑电的混合脑机接口系统
- 机器学习基本概念
- IDEA configure method annotation automatic parameters
- kernel syscore
- busybox之reboot命令流程分析
- 音视频基础
- 5 open source Rust web development frameworks, which one do you choose?
- 双非一本进字节了!!纯干货分享
猜你喜欢

Power BI----几个常用的分析方法和相适应的视觉对象

一周精彩内容分享(第14期)

普林斯顿微积分读本03第二章--编程实现函数图像绘制、三角学回顾

Summary of several defragmentation schemes for MySQL (to solve the problem of not releasing space after deleting a large amount of data)

TOGAF10标准读书会第2场活动精彩继续,高光时刻回顾!

JVS应用中心

Docker安装canal、mysql进行简单测试与实现redis和mysql缓存一致性

JVS函数公式使用场景介绍

安装MYSQL遇到问题:write configuration file卡主

Candence学习篇(11) allegro中设置规则,布局,走线,铺铜
随机推荐
Structural controllability of switched linear systems with symmetry constraints
【Shader】Shader官方示例[通俗易懂]
字符函数和字符串函数
After class, watching the documentation and walking back to the lab, I picked up the forgotten SQL operators again
Is the working process of the belt you know the story - actionreducerstore
使用 Excel 读取 SAP ABAP CDS View 通过 ODBC 暴露出来的数据
机器学习基本概念
串的基本概念与操作
安装MYSQL遇到问题:write configuration file卡主
Selenium自动化测试之Selenium IDE
The latest MySql installation teaching, very detailed
基于C51实现按键控制
Standard SQL/JSON - the sobering part
IDEA configure method annotation automatic parameters
chroot命令
Three-tier architecture service, dao, controller layer
JVS轻应用的组成与配置
JS列表数据通过递归实现树形结构
MySQL面试八股文(2022最新整理)
使用docker搭建mysql主从