fix: Performance and high memory usage of relation hint calculation
* Calculation of hint message when requested relation is not present in schema cache requires creation of a FuzzySet (to use fuzzy search to find candidate tables). For schemas with many tables it is costly. This patch introduces dbTablesFuzzyIndex in SchemaCache to memoize the FuzzySet creation. * Additionally, because of FuzzySet large memory requirements, this patch introduces a limit of 500 relations per schema, above which FuzzySet is not created and hint calculation disabled.
This commit is contained in:
committed by
Steve Chavez
parent
9ec5b030ce
commit
e592d568c6
@@ -11375,12 +11375,34 @@ ALTER TABLE ONLY apflora.zielber
|
||||
|
||||
ALTER TABLE apflora."user" ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
|
||||
CREATE SCHEMA fuzzysearch;
|
||||
|
||||
-- Create many tables to test fuzzy string search
|
||||
-- computing hints for non existing tables
|
||||
DO
|
||||
$$
|
||||
DECLARE
|
||||
r record;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT
|
||||
format('CREATE TABLE fuzzysearch.unknown_table_%s ()', n) AS ct
|
||||
FROM
|
||||
generate_series(1, 499) n
|
||||
LOOP
|
||||
EXECUTE r.ct;
|
||||
END LOOP;
|
||||
END
|
||||
$$;
|
||||
|
||||
DROP ROLE IF EXISTS postgrest_test_anonymous;
|
||||
CREATE ROLE postgrest_test_anonymous;
|
||||
|
||||
GRANT postgrest_test_anonymous TO :PGUSER;
|
||||
|
||||
GRANT USAGE ON SCHEMA apflora TO postgrest_test_anonymous;
|
||||
GRANT USAGE ON SCHEMA fuzzysearch TO postgrest_test_anonymous;
|
||||
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA apflora
|
||||
TO postgrest_test_anonymous;
|
||||
|
||||
@@ -70,3 +70,23 @@ def test_should_not_fail_with_stack_overflow(defaultenv):
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
assert data["code"] == "PGRST205"
|
||||
|
||||
|
||||
def test_second_request_for_non_existent_table_should_be_quick(defaultenv):
|
||||
"requesting a non-existent relationship should be quick after the fuzzy search index is loaded (2nd request)"
|
||||
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_DB_SCHEMAS": "fuzzysearch",
|
||||
"PGRST_DB_POOL": "2",
|
||||
"PGRST_DB_ANON_ROLE": "postgrest_test_anonymous",
|
||||
}
|
||||
|
||||
with run(env=env, wait_max_seconds=30) as postgrest:
|
||||
response = postgrest.session.get("/unknown-table")
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
assert data["code"] == "PGRST205"
|
||||
first_duration = response.elapsed.total_seconds()
|
||||
response = postgrest.session.get("/unknown-table")
|
||||
assert response.elapsed.total_seconds() < first_duration / 10
|
||||
|
||||
Reference in New Issue
Block a user