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 / 问题 / 152209
Accepted
Chris Woods
Chris Woods
Asked: 2016-10-14 08:24:53 +0800 CST2016-10-14 08:24:53 +0800 CST 2016-10-14 08:24:53 +0800 CST

查询变量未正确估计

  • 772

我有一个查询,其中包含多个性能不佳的联接。经过大量分类后,我决定拆开查询,只看驱动表。以下是仅基于驱动表的查询示例。

DECLARE @VAR AS INT

SET @VAR = 11652862

SELECT Field1, Field2
FROM tablea
WHERE Field2 = @VAR

当我按原样运行代码时,实际执行计划会返回 15k 估计行和 1m 实际行。是的,这只是一个简单的SELECT...FROM TABLE,但请记住,这只是更大查询的一部分,因此随着我们添加更多连接,这种估计差异会大大增加。

我知道问题是@VAR因为优化器在将查询编译成计划时不知道变量的值,所以它返回字段估计的平均行数。如果我添加OPTION (RECOMPILE)它将在编译时强制输入值并返回正确的行数。

关键是:这不是我公司可以编辑的自定义代码。它是我无法编辑的第三方应用程序的一部分。更新统计数据无济于事(我查看了直方图,它正确地列出了我的变量的值)。我已经有了这两个领域的覆盖 NC 索引。我能想到的唯一选择是对该查询使用强制执行计划。不过,我从来没有能够成功地做到这一点。有人对强制执行计划有任何其他想法或很好的操作方法参考吗?

由于在评论中被问到,索引的创建语句是:

CREATE NONCLUSTERED INDEX idx ON tablea (Field2)
sql-server performance
  • 1 1 个回答
  • 83 Views

1 个回答

  • Voted
  1. Best Answer
    Joe Obbish
    2016-10-14T15:54:14+08:002016-10-14T15:54:14+08:00

    除了计划指南,我还有其他想法,我会将它们张贴在这里供您考虑,但我不建议实际实施它们。至少有两种不同的方法可以提高 tablea 的行估计值。第一个涉及手动设置统计信息,第二个涉及重定向第三方应用程序以使用您定义的视图而不是直接访问 tablea。

    CREATE STATISTICS 和 UPDATE STATISTICS 都有一个 STATS_STREAM 选项。以下是联机丛书对它的描述:

    标识仅供参考。不支持。不保证未来的兼容性。

    如果这让您无法使用它,那是完全可以理解的,但它允许您做的是将统计数据从一个对象移植到另一个对象。假设您希望将使用 tablea 的查询的基数估计值提高 50 倍。您可以从 tablea 中获取数据,将其复制 50 次,使用 FULLSCAN 收集统计信息,然后使用来自其他表的 STATS_STREAM 值以及 NORECOMPUTE 选项更新 tablea 上的统计信息。您可能还想更改 ROWCOUNT 值。这应该对引用该表的所有查询产生相当大的影响。您可能会遇到其他查询的问题,表中的基础数据发生变化,索引统计信息未更新等等。这不是一个好的选择。

    根据第三方应用程序连接到 SQL Server 的方式,您可以使用与 tablea 不同的架构创建视图,并指示应用程序的该部分在视图中使用。该视图应具有与 tablea 相同的所有列,但应具有增加返回行数的附加代码。我没有那么努力地让它工作,因为它看起来很不切实际,但这种方法的灵感来自 Adam Machanic 关于强制执行并行计划的文章:

    SELECT ta.*
    FROM tablea ta
    CROSS JOIN (
        SELECT t.t
        FROM
        ( 
        VALUES 
        (2), (1), (1), (1), (1), (1), (1), (1), (1), (1), 
        (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), 
        -- lots more values here ...
        (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)
       ) t(t)
    WHERE t % 2 = 0
    ) t
    OPTION (QUERYTRACEON 8690);
    

    我对那个查询不是很满意,但也没有花太多时间在上面。在这种形式下,它对表进行一次扫描,但查询优化器将基数估计高估了 100 倍。TF 8690 用于防止无意义的表假脱机,但这可能不适用于视图或较大的查询。如果同一个应用程序将数据插入到该表中,您需要以某种方式处理它。这不是一个好的选择。

    重申一下,我认为您不应该尝试这两种选择中的任何一种。与供应商交谈会好得多,或者如果这不起作用,请接受它并使用计划指南重试。我对这些没有任何经验,所以我无法提供帮助。

    • 1

相关问题

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

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

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

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