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 1jXq3t-0005o2-9I for pgsql-hackers@arkaria.postgresql.org; Sun, 10 May 2020 17:48:25 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jXq3M-0000zu-JL for pgsql-hackers@arkaria.postgresql.org; Sun, 10 May 2020 17:47:52 +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 <9erthalion6@gmail.com>) id 1jXq3M-0000yG-9A for pgsql-hackers@lists.postgresql.org; Sun, 10 May 2020 17:47:52 +0000 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from <9erthalion6@gmail.com>) id 1jXq3J-0002cQ-Ry for pgsql-hackers@postgresql.org; Sun, 10 May 2020 17:47:51 +0000 Received: by mail-wr1-x441.google.com with SMTP id 50so7532382wrc.11 for ; Sun, 10 May 2020 10:47:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=E5/KrzTstnsULDFleDh91yF+jbUpPg4ikr6YzO07CqE=; b=baSH7MmhPqHKzLUN76twhsOxkUzjRAyrQCBUek7XFHbXodoJp4R11CWcg2Hbib7R+9 dnRh19LBw8aCakrp0H4DO4YZOCC09iznu5WL+GP0PJHKpuKFvHyi5vPl9ft6Hd6Xrpsb SAZRKUKQDQwqcaBVUg7EXhHANJzhIHPELH+gyq7wdkpB7PWz8q5Lehyi4iGIOnBc3gXt C7sk+q7z0k6QSMcdqhjMzr9YlVxBnb8CQQXrjo5n7XoniIcCBFdKWBIYhWCrTAZHLS2m qwJ4yInybCwh8gksOItXXyRxp6aDWpVA0cE/bp1jDlaMNUkNkZcsnf+GdImGLJy0YZma JV9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=E5/KrzTstnsULDFleDh91yF+jbUpPg4ikr6YzO07CqE=; b=WfkaQi/t5cjOrqr9Fq6EDIIplZ8KojNGQmSfJIq/+pUFAFaIA3TzArVrU2cPBhcluC S4gxqlWJPxdNK/jP2aJhTT8Oa8WatPQj2vO384/1rIJr4zYd4bnH5yODLaHayK/+L45E 0ZYMGCLEty3rSxxMQ6EKQhBwi+Xv7RDhjxGJtHv8KcdgexB0lYQgtGdHvE9zUPhqWfCF ZPgaUxTXS3/mVPfMGdrDtAmkfq/dc6lSMGS4a28B0lNpCWnCoSbsUTj1e6VLt7smS8Vs dSSPNR9TJa0mLE5vxIv6SIS4KEiCoTYr0NwWsU68YxaVl6j6cuSBSOOT9gTgdGckxfVz QVhQ== X-Gm-Message-State: AGi0Pub1BOwAt+8hiUrYEhAPOsVLMckyzOaSxVFOM+kexqbDzugQRSeB +N6zj7+b+TLorJvtqM9Dp6c= X-Google-Smtp-Source: APiQypJW4ENHski3pmXMSd5EKM5x2V7TAnjN08zoSk6RCpX4lZWmojFTAFe/ti2u1CSl2u3eT7Z9sg== X-Received: by 2002:adf:fac4:: with SMTP id a4mr13633975wrs.134.1589132867775; Sun, 10 May 2020 10:47:47 -0700 (PDT) Received: from localhost (dslb-094-222-004-201.094.222.pools.vodafone-ip.de. [94.222.4.201]) by smtp.gmail.com with ESMTPSA id y70sm24427039wmc.36.2020.05.10.10.47.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 10 May 2020 10:47:47 -0700 (PDT) Date: Sun, 10 May 2020 19:49:35 +0200 From: Dmitry Dolgov <9erthalion6@gmail.com> To: Dilip Kumar Cc: Floris Van Nee , David Rowley , Kyotaro Horiguchi , Tomas Vondra , Peter Geoghegan , Jesper Pedersen , Alvaro Herrera , Thomas Munro , James Coleman , Rafia Sabih , Jeff Janes , "bhushan.uparkar@gmail.com" , PostgreSQL-development , Alexander Korotkov Subject: Re: Index Skip Scan Message-ID: <20200510174935.teqyazdw6jj6vh47@localhost> References: <20200325085100.5fixaiteuoln4f45@localhost> <20200405161029.fpqqll7xbgfqy5na@localhost> <80ef5f0744f542b18e508fb589a6425a@opammb0562.comp.optiver.com> <20200406163941.rh3okji2rhbnptyt@localhost> <8abe43ac82714c2f9044fb8bac0ebfd0@opammb0562.comp.optiver.com> <20200407194220.edf4nbi7l4cpxk4v@localhost> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk > On Sat, Apr 11, 2020 at 03:17:25PM +0530, Dilip Kumar wrote: > > Some more comments... Thanks for reviewing. Since this patch took much longer than I expected, it's useful to have someone to look at it with a "fresh eyes". > + so->skipScanKey->nextkey = ScanDirectionIsForward(dir); > + _bt_update_skip_scankeys(scan, indexRel); > + > ....... > + /* > + * We haven't found scan key within the current page, so let's scan from > + * the root. Use _bt_search and _bt_binsrch to get the buffer and offset > + * number > + */ > + so->skipScanKey->nextkey = ScanDirectionIsForward(dir); > + stack = _bt_search(scan->indexRelation, so->skipScanKey, > + &buf, BT_READ, scan->xs_snapshot); > > Why do we need to set so->skipScanKey->nextkey = > ScanDirectionIsForward(dir); multiple times? I think it is fine to > just set it once? I believe it was necessary for previous implementations, but in the current version we can avoid this, you're right. > +static inline bool > +_bt_scankey_within_page(IndexScanDesc scan, BTScanInsert key, > + Buffer buf, ScanDirection dir) > +{ > + OffsetNumber low, high; > + Page page = BufferGetPage(buf); > + BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); > + > + low = P_FIRSTDATAKEY(opaque); > + high = PageGetMaxOffsetNumber(page); > + > + if (unlikely(high < low)) > + return false; > + > + return (_bt_compare(scan->indexRelation, key, page, low) > 0 && > + _bt_compare(scan->indexRelation, key, page, high) < 1); > +} > > I think the high key condition should be changed to > _bt_compare(scan->indexRelation, key, page, high) < 0 ? Because if > prefix qual is equal to the high key then also there is no point in > searching on the current page so we can directly skip. From nbtree/README and comments to functions like _bt_split I've got an impression that the high key could be equal to the last item on the leaf page, so there is a point in searching. Is that incorrect? > + /* Check if an index skip scan is possible. */ > + can_skip = enable_indexskipscan & index->amcanskip; > + > + /* > + * Skip scan is not supported when there are qual conditions, which are not > + * covered by index. The reason for that is that those conditions are > + * evaluated later, already after skipping was applied. > + * > + * TODO: This implementation is too restrictive, and doesn't allow e.g. > + * index expressions. For that we need to examine index_clauses too. > + */ > + if (root->parse->jointree != NULL) > + { > + ListCell *lc; > + > + foreach(lc, (List *)root->parse->jointree->quals) > + { > + Node *expr, *qual = (Node *) lfirst(lc); > + Var *var; > > I think we can avoid checking for expression if can_skip is already false. Yes, that makes sense. I'll include your suggestions into the next rebased version I'm preparing.