当前位置:网站首页>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.
边栏推荐
- WebGL给Unity传递参数问题1: Cannot read properties of undefined (reading ‘SendMessage‘)
- Is the working process of the belt you know the story - actionreducerstore
- 文件包含漏洞
- The item 'node.exe' was not recognized as the name of a cmdlet, function, script file, or runnable program.
- Selenium自动化测试之Selenium IDE
- VBA实现双击单元格自动输出对号再次双击取消对号
- 安装MYSQL遇到问题:write configuration file卡主
- 普林斯顿微积分读本03第二章--编程实现函数图像绘制、三角学回顾
- Use ODBC in Excel to read data from CDS view on SAP BTP platform
- 0x80070570文件或目录损坏且无法删除(0x80070091怎么删除)
猜你喜欢

Docker installs canal and mysql for simple testing and achieves cache consistency between redis and mysql

一文带你了解redux的工作流程——actionreducerstore

Data Persistence Technology - MP
给你一个大厂面试的机会,你能面试上吗?进来看看!

JVS函数公式使用场景介绍

Docker搭建Mysql主从复制

Mysql环境变量的配置(详细图解)

这款悄然崛起的国产API接口管理工具,你一定要晓得

机器学习基本概念

TOGAF10标准读书会第2场活动精彩继续,高光时刻回顾!
随机推荐
Docker搭建Mysql主从复制
MySQL模糊查询性能优化
数据持久化技术——MP
[Shader] Shader official example [easy to understand]
How to correctly write the binary stream of the file returned by the server to the local file and save it as a file
带有对称约束切换线性系统的结构可控性
Standard SQL/JSON - the sobering part
busybox之reboot命令流程分析
学习爬虫之Scrapy框架学习(1)---Scrapy框架初学习及豆瓣top250电影信息获取的实战!
ApiPost is really fragrant and powerful, it's time to throw away Postman and Swagger
生信周刊第38期
Spark GC日志分析
榕树贷款GPU 硬件架构
Summary of several defragmentation schemes for MySQL (to solve the problem of not releasing space after deleting a large amount of data)
普林斯顿微积分读本03第二章--编程实现函数图像绘制、三角学回顾
Life is endless, there are more questions, simple questions to learn knowledge points
imx6ull看门狗使用
关于Mysql数据库的介绍
Obsidian设置图床
Quickly learn database management