AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 181543
Accepted
John
John
Asked: 2017-07-24 02:46:02 +0800 CST2017-07-24 02:46:02 +0800 CST 2017-07-24 02:46:02 +0800 CST

为什么 SQL Server 不做复合列统计直方图?

  • 772

SQL Server 有一个叫做“多列统计”的东西,但这并不是人们认为的意思。

让我们看一下下面的示例表:

CREATE TABLE BadStatistics 
(
    IsArchived BIT NOT NULL,
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Mystery VARCHAR(200) NOT NULL
);

CREATE NONCLUSTERED INDEX BadIndex 
    ON BadStatistics (IsArchived, Mystery);

这样,我们就在我们拥有的两个索引上创建了两个统计信息:

BadIndex 的统计数据:

+--------------+----------------+-------------------------+
| All density  | Average Length | Columns                 |
+--------------+----------------+-------------------------+
| 0.5          | 1              | IsArchived              |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 37             | IsArchived, Mystery     |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 41             | IsArchived, Mystery, Id |
+--------------+----------------+-------------------------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0            | 0          | 24398   | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 216602  | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

聚集索引的统计信息:

+--------------+----------------+---------+
| All density  | Average Length | Columns |
+--------------+----------------+---------+
| 4.149378E-06 | 4              | Id      |
+--------------+----------------+---------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 240999       | 240997     | 1       | 240997              | 1              |
+--------------+------------+---------+---------------------+----------------+
| 241000       | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

(我用随机样本数据填充了表,其中大约十分之一的行未​​归档。之后我运行了完整的扫描统计更新。)

为什么两列统计的直方图只使用一列?我知道很多人都写过它确实如此,但理由是什么?在这种情况下,它会使整个直方图的用处大大降低,因为第一列只有两个值。为什么统计数据会被这样任意限制?

请注意,这个问题不是指多维直方图,它是完全不同的野兽。它是关于单维直方图,单维是包含各自多列的元组。

sql-server statistics
  • 1 1 个回答
  • 1574 Views

1 个回答

  • Voted
  1. Best Answer
    Paul White
    2017-08-01T03:49:15+08:002017-08-01T03:49:15+08:00

    背景

    当前的 SQL Server 模型仅使用单列直方图和多列密度信息。单列直方图用于估计合适谓词的选择性,例如a = 1or b > 50。具有多个谓词的查询只是将各个选择性(与假设)结合起来以产生估计的整体选择性。

    例如,请参阅我的文章Cardinality Estimation: Combining Density Statistics

    多列密度通过为多个相等谓词和聚合基数分组提供弱相关信息来进一步通知模型。

    与索引相关的统计信息是该模型的一个机会性附加组件:引擎在构建索引时也可以收集(通常是全扫描)统计信息。SQL Server 自动为其他键构​​造前导列直方图和密度信息。

    索引中非前导列的直方图可以由查询处理器根据需要自动构建,或者预先sp_createstats与@indexonly选项一起使用(等等)。

    多列直方图

    组合单列统计数据(如上)时所做的假设可能会或可能不会足够好地模拟数据的实际情况。在许多情况下,可用的选项(指数退避、独立性、最小选择性)会产生“足够好”的估计。

    我们还将过滤统计信息(和索引)作为低基数前导列索引的自然解决方案,例如问题示例。将这些推向逻辑极端会使我们更接近问题所不涉及的多维统计数据。

    当可用的建模选项无法提供合适的估计时,在某些情况下,多列统计直方图确实可以为合适的索引谓词提供更好的选择性估计。在不同的列中组合不同的数据类型有一些困难,但没有什么不可克服的。

    我们还需要索引键的每个级别的直方图(以获得最佳结果);因此,对于那个索引,除了当前的单列直方图之外(a, b, c),还意味着直方图。(a, b)(a, b, c)(a)

    还需要修改用于检测过时统计信息的机制以维护受影​​响的多列直方图。这些直方图最终可能会比单列统计信息更频繁地重建,这仅仅是因为对更多列的修改会影响它们。

    所有这些都增加了大小、复杂性和维护开销。

    可以使用在引用多列的精心构造的计算列上创建的统计信息来模拟多列统计信息(在有限的范围内)。查询需要在计算列上包含谓词(或基础公式的精确文本匹配)以利用该统计信息。可能只有非常有限的情况下这种方法是可行的。然而,它有一些与自动多列直方图相同的实现问题。

    归根结底,唯一能肯定 SQL Server 不支持多列统计信息的人将是设计者自己。如果您认为您可以为该领域的产品改进提出强有力的理由并具有广泛的适用性,您可以在Connect上或通过您的正常支持渠道提出建议。

    脚注

    在这种情况下,它会使整个直方图的用处大大降低,因为第一列只有两个值

    直方图仍然提供有关前列中值分布的有用信息:构建统计信息时,有 24,398 行IsArchived是false,有 216,602 行是true。

    此外,统计对象告诉我们有 (1 / 0.5) = 2 个不同的值IsArchived,(1 / 4.149378E-06) ~= 241000 个不同的值,(IsArchived, Mystery)平均行大小为 37 字节,并且频率(IsArchived, Mystery, Id)相同每行 4 个额外字节。

    这些都是很好的通用信息,可以与其他列的统计信息相结合,在具有多个谓词的查询中产生选择性估计(如前所述)。

    • 9

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve