◆ knex の whereIn, whereNotIn は配列要素を 1 つ 1 つをパラメータ化する
◆ パラメータ数が 65536 以上になるとエラー
◆ 大きい配列で IN したいなら whereRaw で配列を bind する

knex で whereIn や whereNotIn を使うと指定の配列のどれかに一致するか またはどれにも一致しないかを条件にできます
内部的には SQL の IN が使われていて bind するときには IN の中の要素ひとつひとつをパラメータ化しています
それって IN に指定する配列の要素数がすごく多い場合にパラメータ制限にかからないか心配です

調べてみました

const knex = require("knex")
const pg = knex({ client: "pg", connection: config })

let error

const onError = (err) => {
console.log("ERR")
error = err
}

pg("test")
.whereNotIn("id", Array(10000).fill(0))
.select("*")
.then(console.log, onError)
// [ { id: 1 } ]

id が 1 のレコードだけのテーブルに対して 0 以外という検索をしています
1 件のレコードを取得できると成功です

whereNotIn に指定している配列の要素はすべて 0 で意味のないものですが 自動で重複除去はされないので パラメータ数の制限を調べるにはこれでも大丈夫です

1 万件では問題ないようです

pg("test")
.whereNotIn("id", Array(50000).fill(0))
.select("*")
.then(console.log, onError)
// [ { id: 1 } ]

5 万件でも大丈夫です

pg("test")
.whereNotIn("id", Array(100000).fill(0))
.select("*")
.then(console.log, onError)
// ERR

error.message.slice(-100)
// '$99996, $99997, $99998, $99999, $100000) - bind message has 34464 parameter formats but 0 parameters'

10 万件になるとエラーでした

何件からエラーになるか調べると

Array(65535).fill(0) → OK
Array(65536).fill(0) → ERROR

65535 件までしかできないようです
普通は 1 件 1 件パラメータ化しないと思いますし 十分な量なのでしょう

ですが knex では 1 件ずつパラメータ化してしまいます
配列自体を bind する関数がないか探しましたがなさそうだったので whereRaw を使うことにしました

pg("test")
.whereRaw("NOT(id = ANY(?))", [Array(5000000).fill(0)])
.select("*")
.then(console.log, onError)
// [ { id: 1 } ]

500 万件でも問題なく動作します