PostgreSQL Optimizer如何处理交叉列关联

时间:2014-09-12 16:01:28

标签: sql database postgresql postgresql-9.3

在同一个表的不同中,存储的数据之间通常存在关系或相关性。例如,在customers表中,c_state列中的值受country_id列中的值的影响,因为XYZ的状态仅在ABC国家中找到。

我认为PostgreSQL假设谓词相互独立,并且同一关系中每个谓词的选择性相乘。因此,选择性估计将远小于实际值,并且当数据高度依赖和偏斜时,可以选择非最佳访问路径。如何在PostgreSQL中避免这种情况?

我们可以在PostgreSQL 9.3.5中的一组列上创建某种多列统计信息。是否支持多维直方图

2 个答案:

答案 0 :(得分:7)

你是对的,Pg假定独立,当存在相关性时,这可能是一个问题。分析器不知道如何找到相关性,即使分析仪可以找到它,优化器也不知道如何使用任何此类信息。不支持多维直方图或存储跨列相关信息。

在pgsql-hackers和pgsql-general列表上有关于此的许多讨论,但是没有得到关于如何处理它的确切结论。此外,几乎没有人对此有任何问题,愿意花时间(或资金)投入实际解决问题

这是一个relevant recent articleThe optimizer hints wiki page还涵盖了一些相关问题。

一些邮件列表讨论(非常详尽的列表)包括:

答案 1 :(得分:1)

Postgres 10

更新:Postgres 10获得跨列统计信息,又名扩展统计信息,又名相关统计信息。< / p>

当搜索/排序/分组有点相关的列(例如ZipCode和City)时,请告诉Postgres研究数据以便规划人员提高效率。

CREATE STATISTICS zip_stats_ ( dependencies )
ON zip_ , city_
FROM zipcode_ ;

Database normalization就是要消除行中值之间的functional dependencies。但有时它们仍然是因为去标准化,无论是故意还是无意中。有时我们会有部分依赖,比如ZipCode和City。在这种情况下,如果在搜索,排序或分组时使用这些相关值,请首先使用CREATE STATISTICS命令生成跨列统计信息。

语法

语法很简单。

目前有两种类型的统计信息,dependencies用于函数依赖关系的分析计算,其中1.0表示直接关联,而ndistinct用于对不同值对的n-不同分析。省略类型意味着你想要所有可能的类型,将来可能超过这两种类型。

CREATE STATISTICS [ IF NOT EXISTS ] NAME 
[ type = `dependencies` or `ndistinct` or omit for all types ]
ON col_x , col_y , …
FROM tbl ;

ALTER STATISTICS NAME OWNER TO …
ALTER STATISTICS NAME RENAME TO …
ALTER STATISTICS NAME SET SCHEMA …

DROP STATISTICS [ IF EXISTS ] name

进一步阅读