From 80db1fa872d408f224398ae8d774292f225b66b2 Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Wed, 3 Jun 2026 10:49:59 +0200 Subject: [PATCH] perf(user_ldap): chunk oracle queries for lower bind cost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Oracle's OCI8 driver binds each named parameter individually via OCIBindByName, making queries with 65 000 parameters dramatically slower than on MySQL or PostgreSQL — slow enough to time out in CI and degrade production LDAP syncs on large installations. Lower maxSlices to 5 for Oracle (5 000 params/query) via a match expression alongside the existing SQLite special-case. SQLite and all other databases are unchanged. Assisted-by: ClaudeCode:claude-sonnet-4-6 Signed-off-by: Anna Larch --- apps/user_ldap/lib/Mapping/AbstractMapping.php | 8 +++++++- apps/user_ldap/tests/Mapping/AbstractMappingTestCase.php | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/user_ldap/lib/Mapping/AbstractMapping.php b/apps/user_ldap/lib/Mapping/AbstractMapping.php index 236d337ae8285..5ceb28988d078 100644 --- a/apps/user_ldap/lib/Mapping/AbstractMapping.php +++ b/apps/user_ldap/lib/Mapping/AbstractMapping.php @@ -290,7 +290,13 @@ protected function collectResultsFromListOfIdsQuery(IQueryBuilder $qb, array &$r public function getListOfIdsByDn(array $fdns): array { $totalDBParamLimit = 65000; $sliceSize = 1000; - $maxSlices = $this->dbc->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE ? 9 : $totalDBParamLimit / $sliceSize; + // SQLite's variable limit is very low; Oracle's OCI8 driver has high per-bind overhead, + // making large parameter lists (65k) extremely slow — use smaller batches for both. + $maxSlices = match ($this->dbc->getDatabaseProvider()) { + IDBConnection::PLATFORM_SQLITE => 9, + IDBConnection::PLATFORM_ORACLE => 5, + default => $totalDBParamLimit / $sliceSize, + }; $results = []; $slice = 1; diff --git a/apps/user_ldap/tests/Mapping/AbstractMappingTestCase.php b/apps/user_ldap/tests/Mapping/AbstractMappingTestCase.php index ee5cfc36edc07..7d34ab753b35f 100644 --- a/apps/user_ldap/tests/Mapping/AbstractMappingTestCase.php +++ b/apps/user_ldap/tests/Mapping/AbstractMappingTestCase.php @@ -284,7 +284,7 @@ public function testGetListOfIdsByDn(): void { [$mapper,] = $this->initTest(); $listOfDNs = []; - // List size exceeds the implementation's 65000-parameter chunk limit, forcing multiple chunked queries + // List size exceeds any single-query chunk limit (65k for most DBs, 9k for SQLite, 5k for Oracle), forcing multiple chunked queries for ($i = 0; $i < 66640; $i++) { $name = 'as_' . $i; $dn = 'uid=' . $name . ',dc=example,dc=org';