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 1qybdY-009XYv-89 for pgsql-hackers@arkaria.postgresql.org; Thu, 02 Nov 2023 17:37:44 +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 1qybdV-00EOfp-28 for pgsql-hackers@arkaria.postgresql.org; Thu, 02 Nov 2023 17:37:41 +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 1qybdU-00EOfg-Nz for pgsql-hackers@lists.postgresql.org; Thu, 02 Nov 2023 17:37:40 +0000 Received: from mail-ed1-x534.google.com ([2a00:1450:4864:20::534]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qybdQ-003dVl-Iu for pgsql-hackers@lists.postgresql.org; Thu, 02 Nov 2023 17:37:38 +0000 Received: by mail-ed1-x534.google.com with SMTP id 4fb4d7f45d1cf-53e08e439c7so2165923a12.0 for ; Thu, 02 Nov 2023 10:37:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1698946654; x=1699551454; darn=lists.postgresql.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=nON0u49+IAv+XeEod7u4ku0g2eWNbR5D1NFhk7A+qBc=; b=V/Um5OFc7bC6igxT8D5zJeuLdXfZH+7dz90nbqc43Pmc2TpMVsqwzDzouHFxFd2g4j ZuZo/gOioF5oS/WhjMs09emg2pjz4dSFMs+k49iFdsPYgAuN3nPrktSVnP85b3A+5efb 5E1I828GWP9puoos6/C+RaBowYWzvrgtKWZ9oTIoNxtq1wSSbuyYnQDLx+1JsIOKf1+T PAjqq+M1wpeaxw65eR1b1SUxAGCRVuEyWq2oor7XemlL1HYn80b2epj5e2LrgMieccEi vCEKEL7aTSOiZJ0zG/5aEZ2svTb0xhG/uARwwFsbZmkUS0myD2SyDNI2JNglN0Ld+V5H buSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698946654; x=1699551454; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nON0u49+IAv+XeEod7u4ku0g2eWNbR5D1NFhk7A+qBc=; b=VM6kOJgyJQhQnKkFFLEfE4VpVAjln97WuSgs6uUwrLp4lOMvqnb2Yp0+qJ1kGBudfu XjXtgzdagP3lfxJGUgX9mZ34qeIPwYPf4gA3F/JRAA9YWs8r9j6zNLDt1zrqUH1Iy5VP CqVBvn3EjTurjZZv6Ken0uTCZe4PAh6ogdBi3CHkCNkejj+9sZ/cWWM9sfTdIo2Mc7Sr gTBJsisf/rTs1Fo5fqpdyw3l8xsmA3bM4jYF8RrUwOlxL5+3lSlbcMPNyVUvLs6LZxHo /dp0ishtAY/clfXw5UNOFFwoWPDA220zSCMu+3lmgLQmrKm9OGq73jANks7TYQsUiwb5 UA4g== X-Gm-Message-State: AOJu0Ywnbfc36ij7TB6uuWJ0Ifn6ThYIHuCmJhttYMvmzrlB7p4Ss9zz aDpeWdNuprwdndigzXL2R4Dy8JlTbIcEAM/wZh8= X-Google-Smtp-Source: AGHT+IFxJZJh0jrrKJGuFi5oe0wGF/jf25gEG6naqUyW2s3SAIsGvqwFImY0kmM1pqrusRxLu0+vHQ== X-Received: by 2002:a05:6402:2031:b0:532:c08a:eac0 with SMTP id ay17-20020a056402203100b00532c08aeac0mr16869674edb.26.1698946654014; Thu, 02 Nov 2023 10:37:34 -0700 (PDT) Received: from [10.137.0.17] (srv1.mobissw.com. [89.235.0.226]) by smtp.gmail.com with ESMTPSA id q22-20020a50aa96000000b0053116e45317sm138218edc.44.2023.11.02.10.37.33 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 02 Nov 2023 10:37:33 -0700 (PDT) Message-ID: Date: Thu, 2 Nov 2023 18:37:32 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.15.1 Subject: Re: Postgres picks suboptimal index after building of an extended statistics To: Andrey Lepikhov , Peter Geoghegan Cc: PostgreSQL Hackers References: <0ca4553c-1f34-12ba-9122-44199d1ced41@postgrespro.ru> <6dc348eb-91dd-4163-98fc-af9a9358302a@postgrespro.ru> Content-Language: en-US From: Tomas Vondra In-Reply-To: <6dc348eb-91dd-4163-98fc-af9a9358302a@postgrespro.ru> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 9/25/23 06:30, Andrey Lepikhov wrote: > ... > I can't stop thinking about this issue. It is bizarre when Postgres > chooses a non-unique index if a unique index gives us proof of minimum > scan. That's true, but no one implemented this heuristics. So the "proof of minimum scan" is merely hypothetical - the optimizer is unaware of it. > I don't see a reason to teach the clauselist_selectivity() routine to > estimate UNIQUE indexes. We add some cycles, but it will work with btree > indexes only. I'm not sure I understand what this is meant to say. Can you elaborate? We only allow UNIQUE for btree indexes anyway, so what exactly is the problem here? > Maybe to change compare_path_costs_fuzzily() and add some heuristic, for > example: > "If selectivity of both paths gives us no more than 1 row, prefer to use > a unique index or an index with least selectivity." > I don't understand how this would work. What do yo mean by "selectivity of a path"? AFAICS the problem here is that we estimate a path to return more rows (while we know there can only be 1, thanks to UNIQUE index). So how would you know the path does not give us more than 1 row? Surely you're not proposing compare_path_costs_fuzzily() to do something expensive like analyzing the paths, or something. Also, how would it work in upper levels? If you just change which path we keep, but leave the inaccurate row estimate in place, that may fix that level, but it's certainly going to confuse later planning steps. IMHO the problem here is that we produce wrong estimate, so we better fix that, instead of adding band-aids to other places. This happens because functional dependencies are very simple type of statistics - it has some expectations about the input data and also the queries executed on it. For example it assumes the data is reasonably homogeneous, so that we can calculate a global "degree". But the data in the example directly violates that - it has 1000 rows that are very random (so we'd find no dependencies), and 1000 rows with perfect dependencies. Hence we end with degree=0.5, which approximates the dependencies to all data. Not great, true, but that's the price for simplicity of this statistics kind. So the simplest solution is to disable dependencies on such data sets. It's a bit inconvenient/unfortunate we build dependencies by default, and people may not be aware of there assumptions. Perhaps we could/should make dependency_degree() more pessimistic when we find some "violations" of the rule (we intentionally are not strict about it, because data are imperfect). I don't have a good idea how to change the formulas, but I'm open to the idea in principle. The other thing we could do is checking for unique indexes in clauselist_selectivity, and if we find a match we can just skip the extended statistics altogether. Not sure how expensive this would be, but for typical cases (with modest number of indexes) perhaps OK. It wouldn't work without a unique index, but I don't have a better idea. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company