VadimSurpin opened a new issue, #12490:
URL: https://github.com/apache/gravitino/issues/12490

   ### What would you like to be improved?
   
   `JdbcCatalog`'s namespace/table existence checks (used by namespace 
create/drop, and by every
   table create/drop/exists check) query `iceberg_tables` with a predicate of 
the shape:
   
   ```sql
   ... WHERE catalog_name = ? AND (table_namespace = ? OR table_namespace LIKE 
?)
   ```
   
   `iceberg_tables`'s only index is its primary key, `(catalog_name, 
table_namespace, table_name)`.
   Under PostgreSQL's default locale-aware b-tree operator class, a b-tree 
index cannot bound a
   `LIKE`-prefix range scan (the sort order of a locale-collated index does not 
match byte-prefix
   order), so this predicate degrades to a sequential scan of the entire table 
once it holds a
   non-trivial number of rows. This isn't a hypothetical: we measured it 
directly.
   
   Load-testing a JDBC-backed Iceberg REST catalog (Gravitino) at 100,000 
tables across 1,000
   namespaces on PostgreSQL 16, we found:
   
   - `EXPLAIN ANALYZE` on the live query: ~19.5ms per call (sequential scan), 
vs. ~0.1-0.2ms after
     adding this index.
   - End-to-end benchmark throughput for `NAMESPACE_CREATE`/`NAMESPACE_DROP` 
recovered by
     **100-570x** after adding the index (from ~1.2-1.5 rps to consistent with 
other operations);
     `TABLE_LIST` improved 113-329x; `TABLE_CREATE`/`TABLE_DROP` improved ~4x.
   - The degradation is *silent* - it doesn't show up at small scale (empty or 
lightly-loaded
     catalogs never trigger a sequential scan slow enough to notice), only 
appears once a catalog
     accumulates enough tables, and gets linearly worse from there. Anyone 
running a JDBC-backed
     Iceberg REST catalog against PostgreSQL in production at meaningful scale 
is likely paying this
     cost today without realizing it, because nothing about it produces an 
error - just a slow,
     worsening namespace/table existence check.
   
   ### How should we improve?
   
   Patched `JdbcCatalogWithMetadataLocationSupport` (the JDBC catalog 
implementation the Iceberg REST
   server uses for the `jdbc` backend) now creates a supporting index on the 
shared `iceberg_tables`
   control table right after schema initialization, when the backend is 
PostgreSQL:
   
   ```sql
   CREATE INDEX IF NOT EXISTS gravitino_iceberg_tables_namespace_pattern
   ON iceberg_tables (catalog_name, table_namespace text_pattern_ops)
   ```
   
   This is gated by a new property, `jdbc.create-namespace-index` 
(`gravitino.iceberg-rest.jdbc.create-namespace-index`
   in the REST server config), default `true`. Detection of PostgreSQL is done 
at runtime via
   `DatabaseMetaData#getDatabaseProductName()`, so this is a no-op for MySQL, 
SQLite, H2, and any
   other JDBC backend - no behavior changes for non-PostgreSQL deployments. If 
index creation fails
   for any reason (e.g. the configured database role lacks `CREATE INDEX` 
privileges), a warning is
   logged and catalog initialization proceeds normally; this is a performance 
fix, not a correctness
   one, so it must never block startup.
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to