Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hqboL-0002rz-5X for pgsql-hackers@arkaria.postgresql.org; Thu, 25 Jul 2019 11:21:25 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1hqboI-0008WC-Qy for pgsql-hackers@arkaria.postgresql.org; Thu, 25 Jul 2019 11:21:22 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hqboI-0008SE-Dv for pgsql-hackers@lists.postgresql.org; Thu, 25 Jul 2019 11:21:22 +0000 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hqboF-00005u-45 for pgsql-hackers@postgresql.org; Thu, 25 Jul 2019 11:21:22 +0000 Received: by mail-pg1-x531.google.com with SMTP id u17so22885611pgi.6 for ; Thu, 25 Jul 2019 04:21:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:message-id:to:cc:subject:from:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=6v6HQp8ecxGJWYjl1iMB350ObMvGqdipOcsUwNnIxZU=; b=ng0GvvH6Y8/h3EX5GpJnq6u79jdQReIITVSH1QporkpYCSxrqTUzk4ndODGIOBOnBr hWA66MfnBodnJVM5RasTN5699hFxXkHEhHNhcJXOL6eScfGYXvEvnmiz9ZdMF3Edt/YM CR6jBtljewHaK1y9VlNlqePkFHExjTOMYj2aV1BfWLV4PO7rzzhJ/KG3zDCRyf3fjexr ePP8cJa5k+VaCXQuJ5odyAIFUAG7nAHZTXa8uaAPi/llsREh2L+Tj7xC+LYCKUK8JH25 YqpuhKKVx5XTvCY51mG8I+71xose2P9MelDA0RqySJX9GCH+OhTrpjB/pvD6Kjcw4OG+ Alng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:to:cc:subject:from:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=6v6HQp8ecxGJWYjl1iMB350ObMvGqdipOcsUwNnIxZU=; b=D3ow1z6QyYvf/bJLPgQ3nW5APK3JhtTm2SAbT5q09HxyyZtCNSs0wKZPLaU6m94/iH nFtM9z89bSVsQSKMr5oqPcaFZi4pBJKRPv/QNL0NiFhQqHxq1HptFe6pqW1q2d+wfCvS Ip+g/wKXGLqTDOJrvjcBUeluHjiUaMcxfBl6YSlx+dPO/sqGO5spYRvGEn0UkwRBe/G+ fL97NHBrZUEuq2iGmQ09JAIrhn/GfNnS9DegsOY+w1Tf9+Erqu9udTxTzBDsVCvAfvEo 9JdqpfOG8yEqZ535zkbgFabtC5qCgrp1e0Uivl6rwudhaXEK4EA/zKMFAQT1WfBqUNH3 mEyw== X-Gm-Message-State: APjAAAW5cMKNm/72eL3Z42z6mbx6gmdj5HmlzXge+9D2pf4SDs245mMk OMeQARMq26Q0hJZAI9rKPWw= X-Google-Smtp-Source: APXvYqwbdZ7eLkN7HF4kitfgApLHZTZrbgsOHy6C7pn5VG1ZqBNtANeD1Iv19t5UTyR7pYY8sJwbag== X-Received: by 2002:a62:d0:: with SMTP id 199mr15524408pfa.253.1564053675440; Thu, 25 Jul 2019 04:21:15 -0700 (PDT) Received: from localhost (w204177.dynamic.ppp.asahi-net.or.jp. [121.1.204.177]) by smtp.gmail.com with ESMTPSA id q19sm54310352pfc.62.2019.07.25.04.21.10 (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 25 Jul 2019 04:21:14 -0700 (PDT) Date: Thu, 25 Jul 2019 20:17:37 +0900 (Tokyo Standard Time) Message-Id: <20190725.201737.192223037.horikyota.ntt@gmail.com> To: 9erthalion6@gmail.com Cc: jesper.pedersen@redhat.com, david.rowley@2ndquadrant.com, florisvannee@optiver.com, thomas.munro@gmail.com, jtc331@gmail.com, rafia.pghackers@gmail.com, jeff.janes@gmail.com, pg@bowt.ie, tomas.vondra@2ndquadrant.com, thomas.munro@enterprisedb.com, bhushan.uparkar@gmail.com, pgsql-hackers@postgresql.org, a.korotkov@postgrespro.ru Subject: Re: Index Skip Scan From: Kyotaro Horiguchi In-Reply-To: References: <1d917274-73c1-24de-9faf-c1d2c542cb23@redhat.com> User-Agent: Mew version 6.5 on Emacs 22.2 / Mule 5.0 =?iso-2022-jp?B?KBskQjpnGyhCKQ==?= / Meadow-3.01-dev (TSUBO-SUMIRE) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Hello. At Wed, 24 Jul 2019 22:49:32 +0200, Dmitry Dolgov <9erthalion6@gmail.com> wrote in > > On Mon, Jul 22, 2019 at 7:10 PM Jesper Pedersen wrote: > > > > On 7/22/19 1:44 AM, David Rowley wrote: > > > Here are the comments I noted down during the review: > > > > > > cost_index: > > > > > > I know you've not finished here, but I think it'll need to adjust > > > tuples_fetched somehow to account for estimate_num_groups() on the > > > Path's unique keys. Any Eclass with an ec_has_const = true does not > > > need to be part of the estimate there as there can only be at most one > > > value for these. > > > > > > For example, in a query such as: > > > > > > SELECT x,y FROM t WHERE x = 1 GROUP BY x,y; > > > > > > you only need to perform estimate_num_groups() on "y". > > > > > > I'm really not quite sure on what exactly will be required from > > > amcostestimate() here. The cost of the skip scan is not the same as > > > the normal scan. So other that API needs adjusted to allow the caller > > > to mention that we want skip scans estimated, or there needs to be > > > another callback. > > > > > > > I think this part will become more clear once the index skip scan patch > > is rebased, as we got the uniquekeys field on the Path, and the > > indexskipprefixy info on the IndexPath node. > > Here is what I came up with to address the problems, mentioned above in this > thread. It passes tests, but I haven't tested it yet more thoughtful (e.g. it > occurred to me, that `_bt_read_closest` probably wouldn't work, if a next key, > that passes an index condition is few pages away - I'll try to tackle it soon). > Just another small step forward, but I hope it's enough to rebase on top of it > planner changes. > > Also I've added few tags, mostly to mention reviewers contribution. I have some comments. + * The order of columns in the index should be the same, as for + * unique distincs pathkeys, otherwise we cannot use _bt_search + * in the skip implementation - this can lead to a missing + * records. It seems that it is enough that distinct pathkeys is contained in index pathkeys. If it's right, that is almost checked in existing code: > if (pathkeys_contained_in(needed_pathkeys, path->pathkeys)) It is perfect when needed_pathkeys is distinct_pathkeys. So additional check is required if and only if it is not the case. > if (enable_indexskipscan && > IsA(path, IndexPath) && > ((IndexPath *) path)->indexinfo->amcanskip && > (path->pathtype == T_IndexOnlyScan || > path->pathtype == T_IndexScan) && > (needed_pathkeys == root->distinct_pathkeys || > pathkeys_contained_in(root->distinct_pathkeys, > path->pathkeys))) path->pathtype is always one of T_IndexOnlyScan or T_IndexScan so the check against them isn't needed. If you have concern on that, we can add that as Assert(). I feel uncomfortable to look into indexinfo there. Couldnd't we use indexskipprefix == -1 to signal !amcanskip from create_index_path? + /* + * XXX: In case of index scan quals evaluation happens after + * ExecScanFetch, which means skip results could be fitered out + */ Why can't we use skipscan path if having filter condition? If something bad happens, the reason must be written here instead of what we do. + if (path->pathtype == T_IndexScan && + parse->jointree != NULL && + parse->jointree->quals != NULL && + ((List *)parse->jointree->quals)->length != 0) It's better to use list_length instead of peeping inside. It handles the NULL case as well. (The structure has recently changed but .length is not, though.) + * If advancing direction is different from index direction, we must + * skip right away, but _bt_skip requires a starting point. It doesn't seem needed to me. Could you elaborate on the reason for that? + * If advancing direction is different from index direction, we must + * skip right away, but _bt_skip requires a starting point. + */ + if (direction * indexonlyscan->indexorderdir < 0 && + !node->ioss_FirstTupleEmitted) I'm confused by this. "direction" there is the physical scan direction (fwd/bwd) of index scan, which is already compensated by indexorderdir. Thus the condition means we do that when logical ordering (ASC/DESC) is DESC. (Though I'm not sure what "index direction" exactly means...) regards. -- Kyotaro Horiguchi NTT Open Source Software Center