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 1jvNbM-00017T-PG for pgsql-hackers@arkaria.postgresql.org; Tue, 14 Jul 2020 16:16:16 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jvNbK-0006ay-7f for pgsql-hackers@arkaria.postgresql.org; Tue, 14 Jul 2020 16:16:14 +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 1jvNbJ-0006aq-Uz for pgsql-hackers@lists.postgresql.org; Tue, 14 Jul 2020 16:16:14 +0000 Received: from mail-ej1-x643.google.com ([2a00:1450:4864:20::643]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from <9erthalion6@gmail.com>) id 1jvNbH-0001MF-J2 for pgsql-hackers@postgresql.org; Tue, 14 Jul 2020 16:16:13 +0000 Received: by mail-ej1-x643.google.com with SMTP id n26so22736237ejx.0 for ; Tue, 14 Jul 2020 09:16:11 -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=BB0uB6nqxwVpSlFEqZnjTnlcTPEUjTl9eGZSSbgOR88=; b=Zpb0TTtLo6uUt2rygQ4SAupE1tQu07JWxPzSQDTVgq8Not337i5Z2DyaTJ7nUTgfoj HMgXxQG1cffJB+UXV117Z2rIglKP/EZhay/UvsPlhNxEPh9F14BSgLhIRTIcN0mJ51Ot GAVk8xI8Oy9SQEyqhfe0WVzCEBHsgUlAP46w8YHdadnVQJq3/z1IDEamL19IAgIU1pX2 ILtFkdlgZwMl+AfPmRMs1hbrfRwiUwGZ1kLMj7Z3snFe+Qk4ScpGvupKXa8FhxlMjI40 F0/04vbnPgshakElOrEuS3vBqM5TbbuoJKG7Pma0wcUHfHq172jjMWU951FvRsGSHSVF A7aw== 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=BB0uB6nqxwVpSlFEqZnjTnlcTPEUjTl9eGZSSbgOR88=; b=nXdTSTqsyeQAQPyy/GuZ9zCysrr/FMhJ52duMsbttTb2puo0K/3vMQDCjUne6XahxL MdfTGkWFj93vlP+1lFRz1dl8+ofiD3SSZIuRYl3cgAYAccV3IkDZ40P082rduG+RahCt dOcrR5KeSXNk6GZXZEvmedKY5OjWpuB/flyhLlm53LjK3QM7dx4no2qzDpjz5MFetczx ixasQcLbntvnY/LLxAxL07v7gkZw0TMnLwx5SV6BR60LfZocNKZN9vs/mNdsqT/3M3n5 3MW4maGW2+XR3FL6DVEES+gURG7VRjOmnAAgpHDeOOLzSkgMjsANHFAFRoea8kWr+mMI iFCw== X-Gm-Message-State: AOAM5320phM9aFbXhkkNcsjH35kq5kFUgbBDHQTlgiH3gJozg6XrBf7V q0WmSTXiQlICfjTLUDt0C8c= X-Google-Smtp-Source: ABdhPJwT/Jchy5UHzEYFtApD6FqjPXyuHUOEseZOQA4St5NE/wBmJBGyz6wrbWpdGH4MFWlYsRZNNA== X-Received: by 2002:a17:906:7e04:: with SMTP id e4mr5549968ejr.83.1594743370626; Tue, 14 Jul 2020 09:16:10 -0700 (PDT) Received: from localhost (dslb-178-005-232-008.178.005.pools.vodafone-ip.de. [178.5.232.8]) by smtp.gmail.com with ESMTPSA id cw14sm15041940edb.88.2020.07.14.09.16.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 Jul 2020 09:16:09 -0700 (PDT) Date: Tue, 14 Jul 2020 18:18:52 +0200 From: Dmitry Dolgov <9erthalion6@gmail.com> To: Floris Van Nee Cc: Andy Fan , PostgreSQL-development , Jesper Pedersen , David Rowley , Kyotaro Horiguchi , Peter Geoghegan , Thomas Munro , Tomas Vondra , Dilip Kumar Subject: Re: Index Skip Scan (new UniqueKeys) Message-ID: <20200714161852.s27ikts2dppvbm3h@localhost> References: <20200609102247.jdlatmfyeecg52fi@localhost> <20200629120709.52w2zi36mtzyliv2@localhost> <20200711162103.hiygat3k6wu2d25p@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 Sun, Jul 12, 2020 at 12:48:47PM +0000, Floris Van Nee wrote: > > > > Good point, thanks for looking at this. With the latest planner version there > > are indeed more possibilities to use skipping. It never occured to me that > > some of those paths will still rely on index scan returning full data set. I'll look > > in details and add verification to prevent putting something like this on top of > > skip scan in the next version. > > I believe the required changes are something like in attached patch. There were a few things I've changed: > - build_uniquekeys was constructing the list incorrectly. For a DISTINCT a,b, it would create two unique keys, one with a and one with b. However, it should be one unique key with (a,b). Yes, I've also noticed that while preparing fix for index scan not covered by index and included it. > - the uniquekeys that is built, still contains some redundant keys, that are normally eliminated from the path keys lists. I guess you're talking about: + if (EC_MUST_BE_REDUNDANT(ec)) + continue; Can you add some test cases to your changes to show the effect of it? It seem to me redundant keys are already eliminated at this point by either make_pathkeys_for_uniquekeys or even earlier for distinct on, but could be I've missed something. Along the lines I'm also curious about this part: - ListCell *k; - List *exprs = NIL; - - foreach(k, ec->ec_members) - { - EquivalenceMember *mem = (EquivalenceMember *) lfirst(k); - exprs = lappend(exprs, mem->em_expr); - } - - result = lappend(result, makeUniqueKey(exprs, false, false)); + EquivalenceMember *mem = (EquivalenceMember*) lfirst(list_head(ec->ec_members)); I'm curious about this myself, maybe someone can clarify. It looks like generaly speaking there could be more than one member (if not ec_has_volatile), which "representing knowledge that multiple items are effectively equal". Is this information is not interesting enough to preserve it in unique keys? > - the distinct_pathkeys may be NULL, even though there's a possibility for skipping. But it wouldn't create the uniquekeys in this case. This makes the planner not choose skip scans even though it could. For example in queries that do SELECT DISTINCT ON (a) * FROM t1 WHERE a=1 ORDER BY a,b; Since a is constant, it's eliminated from regular pathkeys. What would be the point of skipping if it's a constant? > - to combat the issues mentioned earlier, there's now a check in build_index_paths that checks if the query_pathkeys matches the useful_pathkeys. Note that we have to use the path keys here rather than any of the unique keys. The unique keys are only Expr nodes - they do not contain the necessary information about ordering. Due to elimination of some constant path keys, we have to search the attributes of the index to find the correct prefix to use in skipping. IIUC here you mean this function, right? + prefix = find_index_prefix_for_pathkey(root, + index, + BackwardScanDirection, + llast_node(PathKey, + root->distinct_pathkeys)); Doesn't it duplicate the job already done in build_index_pathkeys by building those pathkeys again? If yes, probably it's possible to reuse useful_pathkeys. Not sure about unordered indexes, but looks like query_pathkeys should also match in this case. Will also look at the follow up questions in the next email.