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 / 问题 / 236785
Accepted
Gabriele D'Onufrio
Gabriele D'Onufrio
Asked: 2019-04-27 05:35:20 +0800 CST2019-04-27 05:35:20 +0800 CST 2019-04-27 05:35:20 +0800 CST

谁能帮我解决这个糟糕的查询计划?

  • 772

查询:

    SELECT Object1.Column1, Object2.Column2 AS Column3, Object2.Column4 AS Column5, 
Object3.Column6, Object3.Column7,Object1.Column8, Object1.Column9, 
Object1.Column10, Object1.Column11, Object1.Column12, Object1.Column13, 
Object1.Column14, Object1.Column15 as Column15, Object1.Column16, 
Object4.Column4 AS Column17, Object4.Column2 AS Column18, Object1.Column19,
 Object1.Column20, Object1.Column21, Object1.Column22, Object1.Column23, 
Object1.Column24, Object1.Column25, Object1.Column26, Object5.Column4, 
Object1.Column27, Object1.Column28, Object1.Column29, Object3.Column30, 
Object3.Column1 as Column31, Object3.Column32 as Column33, Object1.Column34 
as Column34, ? AS Column35 , Object3.Column36 as Column37 
FROM Object6 AS Object1 
INNER JOIN Object7 AS Object3 ON Object1.Column38 = Object3.Column1 
INNER JOIN Object8 AS Object2 ON Object3.Column30 = Object2.Column1 
LEFT JOIN Object9 AS Object4 ON Object1.Column16 = Object4.Column2 
LEFT JOIN Object10 AS Object5 ON Object1.Column9 = Object5.Column2 
WHERE Object2.Column1 <> ? AND Object1.Column8 = ? 
AND ( coalesce(Column16,?)= ? ) 
AND EXISTS (
         SELECT ? 
         FROM Object11 
         WHERE Column39 = ? 
         AND Column30 = Object3.Column30) 
ORDER BY Column7 desc
OFFSET ? ROWS FETCH FIRST ? ROWS ONLY

这是查询计划

我知道我应该为此添加一个索引:

Database1.Schema1.Object7.Column30, Database1.Schema1.Object7.Column36, Database1.Schema1.Object7.Column6, Database1.Schema1.Object7.Column32

但是其中一列是 varchar 4000,由于该字段的尺寸很大,因此无法创建它。

我注意到仅当返回的行少于获取的第一个数字时才需要 25 秒

sql-server performance
  • 2 2 个回答
  • 626 Views

2 个回答

  • Voted
  1. Best Answer
    Martin Smith
    2019-04-27T08:40:54+08:002019-04-27T08:40:54+08:00

    在此处输入图像描述

    执行计划Object7首先使用非覆盖索引按Column7顺序访问。然后它对该表进行一些键查找,并针对其他表进行嵌套循环连接,最终连接结果到达TOP运算符时仍然按Column7.

    一旦它收到足够的行来满足它,OFFSET ... FETCH它就可以停止从下游操作员那里请求更多的行。Object7.Column7SQL Server 估计在到达该点之前它只需要从初始索引读取 2419 行。

    这个估计根本不正确。事实上,在满足Object7之前,它最终会读取全部行并且可能会用完所有行OFFSET ... FETCH。

    半连接Object11将行数减少了将近一半,但杀手是Object6同一张表上的连接和谓词。这些一起减少了9,753,116来自半连接的行2。

    您可以尝试花一些时间查看所涉及表的统计数据,以尝试从这些连接中获得基数估计更准确,或者您可以添加OPTION (USE HINT ('DISABLE_OPTIMIZER_ROWGOAL') ),以便计划在不假设它可以提前停止的情况下计算成本OFFSET ... FETCH- 这个肯定会给你一个不同的计划。

    • 9
  2. Laughing Vergil
    2019-04-27T09:19:54+08:002019-04-27T09:19:54+08:00

    如果您可以在 Object11 上添加一个索引,Column39 + Column30,并在 Object7 上添加一个索引,Column30,以及在对象 7INCLUDE的语句部分中来自 Object7 的其他字段CREATE INDEX,您应该会有很大的性能提升。这是此查询中涉及的绝大部分资源支出。

    根据计划的 XML,这些似乎接近于此查询的最佳索引:

    CREATE INDEX Idx_Object11_Column39_Column30
    ON Object11(Column39_Column30)
    
    CREATE INDEX Idx_Object7_Column30_Column1_Includes
    ON Object7 (Column30, Column1)
    INCLUDE (Column7, Column36, Column6, Column2)
    
    • 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