为什么我的 node-oracledb execute Promise 解决所需的时间稳步增加?
Why is my node-oracledb execute Promise steadily increasing in the amount of time it takes to resolve?
我正在编写一个与 Oracle
数据库交互的 ETL 工具,该数据库还使用 node-oracledb
1.10
和 RxJS
来处理所有各种异步数据流我正在折腾。我 运行 遇到了一个问题,我的应用程序运行时间越长,调用 node-oracledb
的 .execute()
所需的时间就越长,并且它似乎在 运行 时间线性增加.希望您能发现下面代码中的错误并改正。
首先让我展示一下我是如何运行 Oracle 查询的。我创建了自己的 .execute()
函数,作为 node-oracledb
的 .execute()
的包装器。
import oracledb from 'oracledb';
var oraConnPool;
export function execute(sql, bind, opts) {
if (!oraConnPool) {
createOraPool();
}
return oraConnPool
.then(pool => pool.getConnection())
.then(conn => conn.execute(sql, bind, opts));
}
function createOraPool() {
let oraPool = oracledb.createPool(config.database.oracle);
oraConnPool = oraPool;
return oraPool;
}
还有我的 config.database.oracle
(没有凭据):
{
"poolTimeout": 60,
"poolMin": 10,
"poolMax": 25,
"queueRequests": true,
"queueTimeout": 600000,
"_enableStats": true
}
下面是我调用 .execute()
函数的示例。如您所见,这里发生了很多事情,所以为了清楚起见,让我尝试对其进行一些注释。 rnd
用于为 console.time()
创建一个唯一的 id,因此我可以跟踪 .execute()
Promise
解析所需的时间。让我知道这种时间测量技术是否存在缺陷。传递给 SELECT
语句的绑定输入变量是 ssid 标识符的 csv 字符串,将返回匹配列表。这使我可以批处理记录,而不是为每一行创建一个查询,希望能节省一些执行时间。第一个 .then()
使结果对象数组中的每个键都小写。显然,第二个 .then()
结束了 console.time()
跟踪。
const rnd = Math.random() * 100;
console.time(rnd);
return execute(`
SELECT
ssid_input.ssid AS ssid,
students.id AS student_id,
students.student_number AS student_number
FROM (
SELECT REGEXP_SUBSTR(
:ssids,
'[^,]+', 1, level) AS ssid
FROM dual
CONNECT BY REGEXP_SUBSTR(
:ssids,
'[^,]+', 1, level) IS NOT NULL
) ssid_input
LEFT JOIN students ON students.state_studentnumber = ssid_input.ssid`, {
ssids: {
val: ssids.join(','),
dir: orawrap.BIND_IN,
type: orawrap.STRING
}
}, {
outFormat: orawrap.OBJECT,
maxRows: ssids.length
})
.then(results => {
return results.rows.map(result => {
let newObj = {};
Object.keys(result).forEach(key => {
newObj[key.toLowerCase()] = result[key];
});
return newObj;
});
})
.then(result => {
console.timeEnd(rnd);
return result;
});
下面是 console.time()
输出,它稳定增加直到达到 60000 毫秒 queueTimeout
限制。
97.24179652744425: 12226.930ms
38.14057213652584: 14583.518ms
46.19793585774834: 16024.785ms
16.12600313565251: 17820.694ms
87.73720584788988: 20809.461ms
54.711100085462604: 22652.638ms
42.474404414891744: 24037.868ms
49.09845121453702: 26521.596ms
87.70258724764568: 29461.480ms
1.0731996619882223: 31210.875ms
90.33430329792829: 32259.944ms
37.4829457960367: 34076.824ms
9.731832830291932: 35292.281ms
/home/nathanjones/Projects/test-forge/node_modules/@reactivex/rxjs/dist/cjs/util/subscribeToResult.js:41
root_1.root.setTimeout(function () { throw err; });
^
Error: NJS-040: connection request timeout
我已尝试包含大部分相关代码,如果您需要更多上下文,请告诉我。
编辑:
我在每次调用.execute()
函数时都添加了一个console.log(pool._logStats())
语句。我已经包含了在 NJS-040
错误之前最后一次打印的输出:
Pool statistics:
...total up time (milliseconds): 62823
...total connection requests: 1794
...total requests enqueued: 1769
...total requests dequeued: 0
...total requests failed: 0
...total request timeouts: 0
...max queue length: 1769
...sum of time in queue (milliseconds): 0
...min time in queue (milliseconds): 0
...max time in queue (milliseconds): 0
...avg time in queue (milliseconds): 0
...pool connections in use: 25
...pool connections open: 25
Related pool attributes:
...queueRequests: true
...queueTimeout (milliseconds): 60000
...poolMin: 10
...poolMax: 25
...poolIncrement: 1
...poolTimeout (seconds): 60
...stmtCacheSize: 30
Related environment variables:
...process.env.UV_THREADPOOL_SIZE: undefined
undefined
(这是 node-oracledb Issue 474 的副本)。
您需要确保关闭连接。
您可能需要增加 UV_THREADPOOL_SIZE
,请参阅 Connections and Number of Threads 上的 node-oracledb 文档。
我正在编写一个与 Oracle
数据库交互的 ETL 工具,该数据库还使用 node-oracledb
1.10
和 RxJS
来处理所有各种异步数据流我正在折腾。我 运行 遇到了一个问题,我的应用程序运行时间越长,调用 node-oracledb
的 .execute()
所需的时间就越长,并且它似乎在 运行 时间线性增加.希望您能发现下面代码中的错误并改正。
首先让我展示一下我是如何运行 Oracle 查询的。我创建了自己的 .execute()
函数,作为 node-oracledb
的 .execute()
的包装器。
import oracledb from 'oracledb';
var oraConnPool;
export function execute(sql, bind, opts) {
if (!oraConnPool) {
createOraPool();
}
return oraConnPool
.then(pool => pool.getConnection())
.then(conn => conn.execute(sql, bind, opts));
}
function createOraPool() {
let oraPool = oracledb.createPool(config.database.oracle);
oraConnPool = oraPool;
return oraPool;
}
还有我的 config.database.oracle
(没有凭据):
{
"poolTimeout": 60,
"poolMin": 10,
"poolMax": 25,
"queueRequests": true,
"queueTimeout": 600000,
"_enableStats": true
}
下面是我调用 .execute()
函数的示例。如您所见,这里发生了很多事情,所以为了清楚起见,让我尝试对其进行一些注释。 rnd
用于为 console.time()
创建一个唯一的 id,因此我可以跟踪 .execute()
Promise
解析所需的时间。让我知道这种时间测量技术是否存在缺陷。传递给 SELECT
语句的绑定输入变量是 ssid 标识符的 csv 字符串,将返回匹配列表。这使我可以批处理记录,而不是为每一行创建一个查询,希望能节省一些执行时间。第一个 .then()
使结果对象数组中的每个键都小写。显然,第二个 .then()
结束了 console.time()
跟踪。
const rnd = Math.random() * 100;
console.time(rnd);
return execute(`
SELECT
ssid_input.ssid AS ssid,
students.id AS student_id,
students.student_number AS student_number
FROM (
SELECT REGEXP_SUBSTR(
:ssids,
'[^,]+', 1, level) AS ssid
FROM dual
CONNECT BY REGEXP_SUBSTR(
:ssids,
'[^,]+', 1, level) IS NOT NULL
) ssid_input
LEFT JOIN students ON students.state_studentnumber = ssid_input.ssid`, {
ssids: {
val: ssids.join(','),
dir: orawrap.BIND_IN,
type: orawrap.STRING
}
}, {
outFormat: orawrap.OBJECT,
maxRows: ssids.length
})
.then(results => {
return results.rows.map(result => {
let newObj = {};
Object.keys(result).forEach(key => {
newObj[key.toLowerCase()] = result[key];
});
return newObj;
});
})
.then(result => {
console.timeEnd(rnd);
return result;
});
下面是 console.time()
输出,它稳定增加直到达到 60000 毫秒 queueTimeout
限制。
97.24179652744425: 12226.930ms
38.14057213652584: 14583.518ms
46.19793585774834: 16024.785ms
16.12600313565251: 17820.694ms
87.73720584788988: 20809.461ms
54.711100085462604: 22652.638ms
42.474404414891744: 24037.868ms
49.09845121453702: 26521.596ms
87.70258724764568: 29461.480ms
1.0731996619882223: 31210.875ms
90.33430329792829: 32259.944ms
37.4829457960367: 34076.824ms
9.731832830291932: 35292.281ms
/home/nathanjones/Projects/test-forge/node_modules/@reactivex/rxjs/dist/cjs/util/subscribeToResult.js:41
root_1.root.setTimeout(function () { throw err; });
^
Error: NJS-040: connection request timeout
我已尝试包含大部分相关代码,如果您需要更多上下文,请告诉我。
编辑:
我在每次调用.execute()
函数时都添加了一个console.log(pool._logStats())
语句。我已经包含了在 NJS-040
错误之前最后一次打印的输出:
Pool statistics:
...total up time (milliseconds): 62823
...total connection requests: 1794
...total requests enqueued: 1769
...total requests dequeued: 0
...total requests failed: 0
...total request timeouts: 0
...max queue length: 1769
...sum of time in queue (milliseconds): 0
...min time in queue (milliseconds): 0
...max time in queue (milliseconds): 0
...avg time in queue (milliseconds): 0
...pool connections in use: 25
...pool connections open: 25
Related pool attributes:
...queueRequests: true
...queueTimeout (milliseconds): 60000
...poolMin: 10
...poolMax: 25
...poolIncrement: 1
...poolTimeout (seconds): 60
...stmtCacheSize: 30
Related environment variables:
...process.env.UV_THREADPOOL_SIZE: undefined
undefined
(这是 node-oracledb Issue 474 的副本)。
您需要确保关闭连接。
您可能需要增加 UV_THREADPOOL_SIZE
,请参阅 Connections and Number of Threads 上的 node-oracledb 文档。