Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lIICR-0004YB-2G for pgsql-performance@arkaria.postgresql.org; Fri, 05 Mar 2021 21:41:31 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1lIICQ-0001Vm-1W for pgsql-performance@arkaria.postgresql.org; Fri, 05 Mar 2021 21:41:30 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lIEfz-0003RF-BI for pgsql-performance@lists.postgresql.org; Fri, 05 Mar 2021 17:55:47 +0000 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1lIEfs-0002VP-2M for pgsql-performance@postgresql.org; Fri, 05 Mar 2021 17:55:46 +0000 Received: by mail-wr1-x429.google.com with SMTP id u16so3029757wrt.1 for ; Fri, 05 Mar 2021 09:55:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding:thread-index:content-language; bh=Gw/pwMaKBMszOcoBX8XwJ9dAK/RBcJjzBCZvpHhueM4=; b=vVyK2uzqCiRHny7szS4Dz36oYqttFL3kJuQfj95S5Xc+FIsnFdk2G/Hm8szG0/+xyy FQJKWGSfu7GdOmvDMi/APHBjesK9m2k/ODML9j9aUjcpm8odKuwuBLNVoUQt3JfGrQwX ecyKXx0EqcFcNkUNNkdSqMI1fSrZZ+N6flmuhDp/Kc2vmNBkGurAdbKb7hBbVHtn9RfF Q1XCKUgXnHaw/z4XRlOjNwE9b4LiuuO0FICeV2sWXf3wggqPwjNlmCx8lya6MxMdEZRp iZX0D0SNhJ7dUTEGmau0FDlXLhnivABTrQLzZX1yT4vhCgMFW95zxGpX9+XrBlDDRtnK 2rUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding:thread-index:content-language; bh=Gw/pwMaKBMszOcoBX8XwJ9dAK/RBcJjzBCZvpHhueM4=; b=feD3le93E8enITPddCSv9h9QR1W5yORqr0CMNkJb9c7H3Td62okqlB5duy76ZQHdQt T86S1v0Qfi4iSXlAWw+UFGoMmdXvoAv0yV1L3AqJ/2vzDJ8RXCLqSc5RnK826RPr3LEA M2DzP4xI3jicDOW9WPuJBD+K03I6kMzt1YQznHLkVkZWT+AnA7i92WlbmX0fZBrZaHO1 hEzO4KTlt/4+bgAFe1qLwEzB35HN9bqtBtRfVRHl6Ajg9gZnQbNjRQ6nyMKJgJveYPDn e+9WlWWg7SMIKuKA91EW4IpGw/FFuRyNvtYOz7g+d27eGdCMOjOj3V75HJfYF+4pcF3y QoWw== X-Gm-Message-State: AOAM533tzFbfX8U4EpKxeI8tvYhX5JyrIJZtBZYL6fDny0HRuLhBiy7K kN2UZeHjFbAilMAO9KJBoVkpxUjG4lc= X-Google-Smtp-Source: ABdhPJzS88IdS8R3bTK3niuVwzAXfLld3025QHlb9icD6Zd92Odg9XEwZgUZ0+M/tC3CCtuhHIuIzQ== X-Received: by 2002:a5d:4564:: with SMTP id a4mr10483162wrc.3.1614966938235; Fri, 05 Mar 2021 09:55:38 -0800 (PST) Received: from EMEA28197 ([92.62.10.204]) by smtp.gmail.com with ESMTPSA id l15sm5308349wme.43.2021.03.05.09.55.37 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Mar 2021 09:55:37 -0800 (PST) From: To: Subject: Slow query performance inside a transaction on a clean database Date: Fri, 5 Mar 2021 17:55:37 -0000 Message-ID: <002101d711e8$bfd8a490$3f89edb0$@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 16.0 Thread-Index: AdcR1cXeG6VI12zwTQSlRwWlcIv0IA== Content-Language: en-gb List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi everyone, I have a SELECT query that uses a long chain of CTEs (6) and is executed repeatedly as part of the transaction (with different parameters). It is executed quickly most of the time, but sometimes becomes very slow. I managed to consistently reproduce the issue by executing a transaction containing this query on an empty database. The query is fast for the first 150-170 inserted resources, but ~50% of the executions afterwards take 5.6s instead of 1.4ms. Additionally it only becomes slow if resources are inserted in a random order, if I insert resources sorted by `start_date_time` column the query is always fast. The slow query is part of the transaction (with Repeatable Read isolation level) that executes *create if not exists* type flow for 211 resources. Each resource insertion, inserts multiple rows into each table. Each resource has a unique `resource_surrogate_id`, which is part of every row inserted for that resource. Inside a transaction search is performed using values for a resource, before that resource is inserted, hence it always returns 0 rows (only date values are changing and never overlap). Resources are inserted in the order of increasing `resource_surrogate_id` (only `resource_type_id == 52` rows are part of the transaction). Some more info about the CTEs: - cte0: always matches N rows (from 5*N rows inserted for each resource) - cte1: always matches N rows (from 5*N rows inserted for each resource) - cte2: always matches N rows (from 17*N rows inserted for each resource) - cte3 when combined with cte4: always matches 0 rows (from 2*N rows inserted for each resource) - (if insertions are ordered by start_date_time, cte3 matches 0 rows, and query is fast - execution plan not included) Here are the results of EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON): - Slow: https://explain.depesz.com/s/e4Fo - Fast: https://explain.depesz.com/s/7HFJ I have also created a gist: https://gist.github.com/anyname2/e908d13d515e8970e599eb650cab15fe - init.sql - is a script to create tables and indexes - parametrized-query.sql - is the query being executed - pgdump.sql - database dump PostgreSQL Version: PostgreSQL 13.2 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.2.1_pre1) 10.2.1 20201203, 64-bit Setup: PostgreSQL is running inside a docker container (with default parameters), issue is reproducible both in the Kubernetes cluster and locally. Can anyone help diagnose this? There are a few question I have: - Repeatable Read transaction is running on an empty database, hence it should not match anything. Why are resources inserted in the current transaction considered in the query? (if I understood the execution plan correctly) - What causes the slow case? How can I rewrite the query to avoid the slow case? - Is it my query not optimised? Or should the execution planner handle it better somehow? Thank you, Valentinas