统计。多列直方图可能吗?


13

我正在考虑以下情况:我有两根高密度色谱柱,但这些色谱柱不是独立的。

定义

这是我出于测试目的而创建的表的定义。

CREATE TABLE [dbo].[StatsTest](
    [col1] [int] NOT NULL,  --can take values 1 and 2 only
    [col2] [int] NOT NULL,  --can take integer values from 1 to 4 only
    [col3] [int] NOT NULL,  --integer. it has not relevance just to ensure that each row is different
    [col4]  AS ((10)*[col1]+[col2])  --a computed column ensuring that if two rows have different values in col1 or col2 have different values in col4 
) ON [PRIMARY]

数据

实验数据如下

col1    col2    col3    col4
1       1       1       11
1       2       2       12
1       2       3       12
1       3       4       13
1       3       5       13
1       3       6       13
1       4       7       14
1       4       8       14
1       4       9       14
1       4       10      14
2       1       11      21
2       1       12      21
2       1       13      21
2       1       14      21
2       2       15      22
2       2       16      22
2       2       17      22
2       3       18      23
2       3       19      23
2       4       20      24

步骤1:按col1过滤

SELECT * FROM StatsTest WHERE col1=1

正如预期的那样,查询优化器会猜测确切的行数。 实际行数= 10,估计行数= 10

步骤2:按col2过滤

SELECT * FROM StatsTest WHERE col2=1

同样,我们有一个完美的估计。

实际行数= 5,估计行数= 5

步骤3:按col1和col2进行过滤

SELECT * FROM StatsTest WHERE col1=1 AND col2=1

在此,估计远非接近实际的行数。 实际行数= 1,估计行数= 3,53553

问题是查询分析器隐式地假定col1和col2是独立的,但它们不是独立的。

步骤4:按col4过滤

SELECT * FROM StatsTest WHERE col4 = 11

我可以通过COL4 = 11过滤,以获得相同的结果,在步骤3中的查询,因为COL4是计算列并根据该方式,它已被定义COL1 = 1和COL2 = 1相当于COL4 = 11 但是在这里, ,正如预期的那样,估算是完美的。

实际行数= 1,估计行数= 1

结论/问题

在处理两个或多个非独立列的过滤时,这种人工的,不雅致的解决方案是否是实现准确估计的唯一可用选择?为了获得实际精度,计算列和计算列的过滤器是否严格必要?

sqlfiddle中的示例


为什么不在col1 / 2上建立一些索引呢?
LowlyDBA 2014年

实际上我做了,但是我没有包括在这里,因为它没有用。对于直方图,仅考虑第一列,并且密度仅考虑值的不同数量,而不考虑其分布
JGA 2014年

Answers:


15

多列直方图可能吗?

不是真正的多维直方图,不。

当处理两个或多个非独立列的过滤时,这种人工的且不雅致的解决方案是否是实现准确估计的唯一可用选项?

SQL Server确实支持“多列”统计信息,但是除了第一个命名列上的直方图之外,它们仅捕获平均密度(相关)信息。它们仅对相等比较有用。

平均密度信息不会捕获任何细节,因此对于两列统计对象上的任何一对值,您将获得相同的选择性。在某些情况下,多列统计可能足够好,总比没有好。多列统计信息自动建立在多列索引上。

根据SQL Server的版本,您也许还可以使用过滤索引过滤统计信息

-- Filtered statistics example
CREATE STATISTICS stats_StatsTest_col2_col1_eq_1
ON dbo.StatsTest (col2)
WHERE col1 = 1;

CREATE STATISTICS stats_StatsTest_col2_col1_eq_2
ON dbo.StatsTest (col2)
WHERE col1 = 2;

或者,您可以构建索引视图(可以支持其自身的索引和统计信息)。索引视图是DATE_CORRELATION_OPTIMIZATION数据库设置背后的机制,数据库设置是一种很少使用的表间关联功能,但适用于问题的实质。

为了获得实际精度,计算列和由计算列进行的筛选是否严格必要?

这不是唯一的方法。除了已经提到的内容,您还可以指定计算列的确切文本定义,并且优化程序通常会将其与计算列的统计信息进行匹配。

还存在跟踪标志,这些标志会更改有关多列关联的假设。此外,SQL Server 2014中的默认相关假设(启用了新的基数估计器)从“独立性”更改为“指数补偿”(此处此处有更多详细信息)。最终,这只是一个不同的假设。在许多情况下会更好,而在其他情况下会更糟。

获得良好的执行计划并不总是需要基数估计的精确度。在生成可以针对不同参数值重用的计划与对于特定执行最优化但不能重用的计划之间始终存在权衡。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.