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 1llBQb-00086T-O9 for pgsql-bugs@arkaria.postgresql.org; Mon, 24 May 2021 14:19:34 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1llBQa-0007d1-Iz for pgsql-bugs@arkaria.postgresql.org; Mon, 24 May 2021 14:19:32 +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 1llBQa-0007c8-6y for pgsql-bugs@lists.postgresql.org; Mon, 24 May 2021 14:19:32 +0000 Received: from mail-ed1-x531.google.com ([2a00:1450:4864:20::531]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1llBQW-0002Ez-NU for pgsql-bugs@lists.postgresql.org; Mon, 24 May 2021 14:19:31 +0000 Received: by mail-ed1-x531.google.com with SMTP id df21so32175985edb.3 for ; Mon, 24 May 2021 07:19:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb-com.20150623.gappssmtp.com; s=20150623; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=MtwpOYylL3Hfuwm21yK4un4FWpyngIC5fER1DA6M89w=; b=PWN+V76jfCsArJDr6yI4BWvvveGMwmkX4BIGVnU1RI//mC2c9Zz6AKhC8TwFsw4BeE 52TCAOqhmKp4ftNqTG7jsuA0qWk2zrgKy7cVxTSP43lCIpWFq7eUTHGRfbSvK97jpWl2 HnJh2xk2LtFGGbzBMfPk/CqSAfbFjdmzhguV5qND9blrz8IBk9dcuJFXKWAszhDqOzLr p2tgLp6+j51ULvj7oB+aACjsoM8/YFChUMs/CG6plFRcdrxz95+BBz1eV1o2+qD+u/CD EUBcce+a0k97OUH8IaVYZcTBBdrx4VUJRBRfAPUNazu3uNFvMaL+y0tc6v1qcLDNPMGY LvJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=MtwpOYylL3Hfuwm21yK4un4FWpyngIC5fER1DA6M89w=; b=g+ISF8vI8vKr2k8wx1kKmhvlb5R43XrVsSeJF/j+/xt9oAAYy49GljlUe/vcm7Hzw9 IvgQavOmaXN5EoKuyh3lhmU+TWTLeRD6Hj8zE8CexW2ttrlG0exQktjNVcXuQKBl3lwX FBos61ISaKBW+X1AVTtad11nTHTbt6fUwL0zHiGn0X2ygInucTOOuniK45JmkE4VdHRe 8Ewu4Ubz4uHbeegCFUr7shXqDeQ0PK2LnUh06V5uwp/gSN4vwC8o8tMWyOssyj8+jY/V vZWiRCiZTNVMss483oQW5SxlsLQfWEWNjPhfXmgSRG1tJTPoApwPQApJ54F2XpckkPdC CpVQ== X-Gm-Message-State: AOAM533XUXyZp2S7F0kRrb2/8WqpQzLNBUOLaWKsxxadqktU61bc03Tg kROSqa/jXwJ+3tLX4/5fzLB7URnlU/b4LIhQXz1PzCgVfrPLMQYAyxhxXTqKIBWFUDyUw6rA0Aw YHT4v5y/5GY3pog5JzTWOvdTAdcehvxXPeqzRFBpTUciLvEgO+dxnttODnLzsGYOeu8Sd0/XS6U K8pmi74gZmj6vUOJBMdfJB80pR/nw9rf43qI9eK+SUOSFA/ZvYff8qT3y7Oa+Q8FKZUXhI56kW6 V+MWnPHZYp3YZ4jHgaVj4kxpFWWMkkb+40HrIM8jIzrC9U/ X-Google-Smtp-Source: ABdhPJya6aG1bwObev9kRv0UyZbMXJAMhTfLAnpb9dyJLv8vD63WkiAXdisdzDdC2P1q9s84OgvHug== X-Received: by 2002:aa7:d5cf:: with SMTP id d15mr25801238eds.153.1621865966403; Mon, 24 May 2021 07:19:26 -0700 (PDT) Received: from [10.137.0.19] (ip-86-49-254-183.net.upcbroadband.cz. [86.49.254.183]) by smtp.gmail.com with ESMTPSA id e22sm9834949edu.35.2021.05.24.07.19.25 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 24 May 2021 07:19:26 -0700 (PDT) Subject: Re: Query is slow when order by and limit clause are used in the query To: Bharath Rupireddy , sreekanth vajrapu Cc: pgsql-bugs@lists.postgresql.org References: From: Tomas Vondra Message-ID: Date: Mon, 24 May 2021 16:19:24 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.10.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-CLOUD-SEC-AV-Info: enterprisedb,google_mail,monitor X-CLOUD-SEC-AV-Sent: true X-Gm-Spam: 0 X-Gm-Phishy: 0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 5/24/21 2:28 PM, Bharath Rupireddy wrote: > On Mon, May 24, 2021 at 5:01 PM sreekanth vajrapu > wrote: >> >> Hi Bharath, >> >> Thanks for the quick reply, I have attached the execution plan for below 3 scenarios. Our application is using 1st Scenario >> >> 1) WITH ORDER BY AND LIMIT 30 -- Very slow(3 to 5 seconds) >> 2) WITH ORDER BY WITHOUT LIMIT -- Very fast(160 MS) >> 3) WITH ORDER BY WITHOUT LIMIT 100 -- Very fast(160 MS) >> >> Kidney let me know if you need any more details on this. > > I see that there are a huge number of Heap Fetches: 599354 with LIMIT > 30 clause vs Heap Fetches: 11897 without LIMIT clause, maybe that > could be the reason for the slowness. I'm not sure why this is > happening with the LIMIT 30 clause only. Is it that this issue happens > every time? Say, if you run with LIMIT 30, then the query finishes in > 3-5sec. Immediately if you run without a LIMIT clause then the query > completes in 160ms. Is vacuum running successfully on the tables and > indexes for which there's a huge number of heap fetches? > But the heap fetches are in the index-only part of the plan, and it matches the number of loops for that node. There are 521996 loops and 599354 heap fetches, so roughly 1:1, i.e. roughly the same ratio as for the faster plans. It's hard to give advice when we only have the plans, not the original queries and index definitions, and when the plans are "anonymized" in a rather inconsistent way (hard to say how the tables/indexes match between the queries). If I had to guess, I'd say this is a case of the usual LIMIT problem, where the optimizer assumes the matching rows are uniformly distributed in the input relation, when in reality it's "concentrated" at the end. For example, imagine you have a table with two random columns: CREATE TABLE t (a int, b int); INSERT INTO t SELECT 100 * random(), 100 * random() FROM generate_series(1,1000000) g; CREATE INDEX ON t (a); Now imagine you do this: SELECT * FROM t WHERE a = 10 AND b = 20 LIMIT 1; In this case there's ~10000 rows with a=10, and we can fetch that from the index. And we know there's ~100 groups with different b values, distributed uniformly in the 10k rows. So if we start scanning the index, after ~100 rows we should get a value with b=20, in which case LIMIT 1 is done. Now imagine the values are not distributed uniformly like this, but instead we have this: INSERT INTO t SELECT i/10000, i/10000 FROM generate_series(1,1000000) s(i); In this case the DB will still believe it'll only scan ~100 rows, but there are no rows with a=10 and b=20, so it'll end up scanning all 10k rows with a=10. Or maybe all the "b=20" rows are at the very end of the index, or something like that. Perhaps the "delete" column makes it behave like this. This is only an issue for queries with LIMIT, because that pushes the planner to pick a plan with very low startup cost. But those plans often have very high total cost, and degrade poorly when the uniformity assumption is incorrect. Hard to say, though, confirming it would require looking at the data more closely. The one thing I'd suggest is changing the xxxx_index to also include the "deleted" column, but it's a stab in the dark. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company