Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tnK3i-004Eo6-AB for pgsql-performance@arkaria.postgresql.org; Wed, 26 Feb 2025 16:14:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tnK3h-008mth-8e for pgsql-performance@arkaria.postgresql.org; Wed, 26 Feb 2025 16:14:53 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tnK3g-008mtZ-Pr for pgsql-performance@lists.postgresql.org; Wed, 26 Feb 2025 16:14:52 +0000 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tnK3d-000DME-0W for pgsql-performance@lists.postgresql.org; Wed, 26 Feb 2025 16:14:51 +0000 Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-4394036c0efso45439935e9.2 for ; Wed, 26 Feb 2025 08:14:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bowt-ie.20230601.gappssmtp.com; s=20230601; t=1740586487; x=1741191287; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=lxtcYwrn/TFEjgTCrf3giwTy8ht4BBAAoAbIwfHeQqo=; b=F8VCOxQyfQt6L7qWoK/2vsO/IJkDxOeIJ6x6Qs2sgCyRAW6rNV7+7ikZmiWHiCFCgS skuKO2zJnrkZKCsnIpw4PaKA1N+rw9/u8x3HEnwuay+hBGwHSpZeB314qYhsUvDXEck8 Qwx7KrukINjFZu+E9Rxghg6jCHcAScsEk6i4sB6jXGHFZRenOAgHjrzCKap4MiiaLEXV KHWj5oDPy/dTp8nWtS3PWlk4EIX2JAc0FTRON5boBKYtEhJoEKwGgc039X1YmOfzCFEq LhHmsbWNA336GGUB2iyVqs3vxE0p8HD6jkqp2r5JvpIDHzug6h5wTlagB6BZ+wrL0V3+ ExAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740586487; x=1741191287; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lxtcYwrn/TFEjgTCrf3giwTy8ht4BBAAoAbIwfHeQqo=; b=LBIL/HrTKRiNi0dLrxytA1n//q2m2zfFCmtof4R2Vyq1SuZ4kKhDH/F3rm5/oqLB8J spSiDTTEPV2Xh/OZ4iTgZUB8VslRiqjsXRZ9oRNbIQRwg/PvOaRaGfjFmaJq7DMYteM1 nyeaX/v1hTTiH82a8UEfnCKw6W/MY2G4ayBZzxWEkIrPsCzOv79PDbwXoQLukOnja9pl 57T3WNgBKWqC7qElGlzhkj2vl8VToszZ28dA4guxxwgBxxXXDJUC/9HsBXuojkPGN4t/ am7wTDLVbXemvDtFt8r8Fn2KwAv2YAZni7f4olwx91dxuFOSfK2pDo8AUYa6lxtKkpts H8gA== X-Gm-Message-State: AOJu0YwZ6OPz7F0OVxNaT6aZ90zV8Foo0JHNInJDaZgxghGiZqXL6vjd Q2mdKdGI88GaCAhgWFmLbY4ktRakCjct+P/NHPHmtB6ReSb9KOVTQ81j1qcqcoGXvCjASGGPDBP hXfotkTGJM9ZKmD7ZAjyVnc/TESe6dGWkN7aYJ+0cvptk1osi2n4= X-Gm-Gg: ASbGncskTyVPZUaKK/vhsQyQ4h9OzWxNe5l3t6NvFU9yZ74qmvzqtxr0qNeNadJSLyu eu6AeqnO3qm+OXACviKw/d+YTNtRufN5BmU21teBnv/q+4OjX4mjGQQsf9P3huewwcvFm9Qm5yz u4i9tcXyM= X-Google-Smtp-Source: AGHT+IHjWW6qjj8nLnY+i9Nh4TjdL/+7AtT2NIB1OkzzFJm8qXvgShAFalZpUebVTICbCPCgQDReR+4dpHQU3Lq8kwE= X-Received: by 2002:a5d:6d82:0:b0:390:d777:6505 with SMTP id ffacd0b85a97d-390d7776649mr2413360f8f.19.1740586487237; Wed, 26 Feb 2025 08:14:47 -0800 (PST) MIME-Version: 1.0 References: <32308394-e197-4a9f-9dbe-336e8af6da58@app.fastmail.com> In-Reply-To: <32308394-e197-4a9f-9dbe-336e8af6da58@app.fastmail.com> From: Peter Geoghegan Date: Wed, 26 Feb 2025 11:14:21 -0500 X-Gm-Features: AQ5f1Jq6Sb7qRmA9aax0oXhRaBxreK9l4D7aieDPOZMIUei912NkkIv_ia4DvmI Message-ID: Subject: Re: Efficient pagination using multi-column cursors To: large.goose2829@salomvary.com Cc: pgsql-performance@lists.postgresql.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, Feb 26, 2025 at 10:40=E2=80=AFAM wr= ote: > My understanding is that given this "mixed order" index: > CREATE INDEX data_index_desc ON data (col_1, col_2 DESC, col_3); > > The index tuples are physically organized exactly in this way: > ORDER BY col_1, col_2 DESC, col_3 > > So that I should be able to write a query that reads a continuous range f= rom this index without filtering. Yes, you can. For example, if you use the predicate "col_1 >=3D 10", it can work in this way, even with a mixed-asc-and-desc order multicolumn index -- without any filtering. Same thing if you don't have any predicate at all -- there's no lower-order columns to filter on because there's no columns to filter on at all. The actual predicate that you're interested in isn't like that. It cannot use an index that both returns rows in the mixed-ASC-and-DESC order that you want (and so terminate early with a LIMIT and whatnot), while at the same time accessing all the tuples as exactly one contiguous group. You have to pick which is more important. It sounds very much like having the most useful sort order is important. > Does this mean that it is not possible to come up with a plan that has th= e same performance as "WHERE (col_1, col_2, col_3) > (10, 20, 29)" using "h= andwritten" filters, or only for "mixed order"? Or not a theoretical limita= tion but a limitation of the current implementation of the query planner? Perhaps the query planner should be taught to rewrite the query in such a way as to make it unnecessary for you to do so -- I think that that's what MySQL is doing for you. That is beside the point. Again, think about how things are physically laid out in an index which mixes ASC and DESC order. It is inevitable that the scan has to traverse over non-matching tuples in order to read all of the matching tuples (or to read a given number of matching tuples). This has nothing to do with the query planner. > Aka. "Good, Fast, Cheap =E2=80=94 Pick Any Two" ;) It's not like that. Often it just isn't necessary to pick any 2 -- you can have all 3, because the requirements of the query allow it. (Plus it would never make sense to pick the first and second stars over the third.) --=20 Peter Geoghegan