当前位置:网站首页>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.
边栏推荐
- 榕树贷款GPU 硬件架构
- file contains vulnerabilities
- Addition logic for SAP Commerce Cloud Product Review
- Full GC (Ergonomics)排查分析
- 想吃菌子,当然是自己上山找了
- WebGL给Unity传递参数问题1: Cannot read properties of undefined (reading ‘SendMessage‘)
- 这款悄然崛起的国产API接口管理工具,你一定要晓得
- Different lower_case_table_names settings for server (‘1‘) and data dictionary (‘0‘) 解决方案
- A40i/T3 uboot启动时对PMU部分初始化
- 5 open source Rust web development frameworks, which one do you choose?
猜你喜欢
普林斯顿微积分读本03第二章--编程实现函数图像绘制、三角学回顾
Docker搭建Mysql主从复制
kernel syscore
Service discovery of kubernetes
Docker practical experience: Deploy mysql8 master-slave replication on Docker
MySQL日志中“binlog”的三种格式玩起来真爽
Selenium自动化测试之Selenium IDE
Android studio connects to MySQL and completes simple login and registration functions
MySQL面试八股文(2022最新整理)
一文吃透接口调用神器RestTemplate
随机推荐
安装MYSQL遇到问题:write configuration file卡主
在 Excel 里使用 ODBC 读取 SAP BTP 平台上 CDS view 的数据
Obsidian设置图床
[core]-ARMV7-A、ARMV8-A、ARMV9-A 架构简介「建议收藏」
一文吃透接口调用神器RestTemplate
三相PWM整流器预测直接功率控制
深度学习基本概念
基于生物激励神经网络的室内实时激光SLAM控制方法
B/S架构模式的一个整体执行流程
LeetCode - 025. 链表中的两数相加
Spark GC日志分析
Comparison of ipv4 and ipv6 (IPV4)
A Week of Wonderful Content Sharing (Issue 14)
Life is endless, there are more questions, simple questions to learn knowledge points
PAT exam summary (exam experience)
双非一本进字节了!!纯干货分享
vb.net 画曲线
Quickly learn database management
基于姿态估计的护具佩戴检测与动作识别
ESP8266-Arduino编程实例-PIR(被动红外)传感器驱动