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 / 问题 / 323625
Accepted
John K. N.
John K. N.
Asked: 2023-02-17 06:09:38 +0800 CST2023-02-17 06:09:38 +0800 CST 2023-02-17 06:09:38 +0800 CST

在列列表中带有 , * 的 SELECT 语句比没有 * 的相同语句更快

  • 772

情况

当使用包含一组已定义列的 SELECT 语句查询数据库时,大约 21 秒内会收到结果。

, *如果在定义的列集列表末尾有一个额外的星号 ( ),则查询将在 2 秒内返回结果。

查询执行计划

执行计划有很大不同。

您可以使用 PasteThePlan 中的链接找到好的实际查询执行计划和坏的实际查询执行计划。

列列表中包含 , * 的语句(末尾)


            SELECT    -- DISTINCT -- 27.04.2020
                'SchuelerKlasse' AS EcoQuery,
                VX_PERSON.PER_MAN_ID, VX_PERSON.PER_ID, VX_PERSON.PER_NAME, VX_PERSON.PER_VORNAME, VX_PERSON.PER_LB_PER_ID, 
                VX_PERSON.PER_GESCHLECHT, VX_PERSON.PER_GEBURTSDATUM, VX_PERSON.PER_TELP, VX_PERSON.PER_MAILP, VX_PERSON.PER_NATP, VX_PERSON.PER_VERSICHERTENNUMMER, VX_PERSON.PER_LAND,
                VX_ADRESSE.ADR_STRASSE, VX_ADRESSE.ADR_PLZ, VX_ADRESSE.ADR_ORT,
                VX_KLASSE.KL_CODE, VX_KLASSE.KL_BEZEICHNUNG,
                VX_KLASSEABSCHNITTSCHUELER.KAS_ANMELDE_STATUS, 
                VX_KLASSEABSCHNITTSCHUELER.KAS_ANMELDETYP, VX_KLASSEABSCHNITTSCHUELER.KAS_ABSCHNITTSNR,
                VX_KLASSE_ZEITRAUM.KLZ_IS_ABSCHLUSSKLASSE, VX_KLASSE_ZEITRAUM.KLZ_ZR_NR,
                VX_ZEITRAUM.ZR_BEGINN, VX_ZEITRAUM.ZR_ENDE
                ,'' AS FA_CODE
                ,'' AS FA_BEZ_STP, '' AS FA_BEZ_STP_LANG
                , '' AS EcoOrig_FA_CODE, '' AS EcoOrig_FA_BEZ_STP, '' AS EcoOrig_FA_BEZ_STP_LANG
                , VX_ANGEBOT.ANG_BEGINN
            
 ,* 

            FROM 
                ECOLST.VX_KLASSE_ZEITRAUM, 
                ECOLST.VX_PERSON, 
                ECOLST.VX_KLASSE, 
                ECOLST.VX_KLASSEABSCHNITTSCHUELER, 
                ECOLST.VX_ZEITRAUM, 
                ECOLST.VX_ADRESSE 
                , ECOSYS.T_KLASSE
                , ECOLST.VX_ANGEBOT

            WHERE  
                    VX_KLASSE_ZEITRAUM.klz_kl_id = VX_KLASSE.kl_id 
                AND VX_KLASSE_ZEITRAUM.klz_zr_id = VX_ZEITRAUM.zr_id 
                AND VX_KLASSEABSCHNITTSCHUELER.kas_ang_id = VX_KLASSE.kl_ang_id 
                AND VX_KLASSEABSCHNITTSCHUELER.kas_zr_id = VX_ZEITRAUM.zr_id 
                AND VX_KLASSEABSCHNITTSCHUELER.kas_per_id = VX_PERSON.per_id 
                AND VX_KLASSEABSCHNITTSCHUELER.kas_kl_id = VX_KLASSE.kl_id 
                AND VX_KLASSEABSCHNITTSCHUELER.KAS_ANMELDE_STATUS LIKE 'De%'  -- LIKE 'Definitiv%'
                AND VX_PERSON.per_id = VX_ADRESSE.adr_per_id 
                AND VX_PERSON.per_man_id = VX_KLASSE.kl_man_id
                AND VX_KLASSE.KL_ANG_ID = VX_ANGEBOT.ANG_ID
                AND VX_KLASSE.KL_MAN_ID = 15 
                AND VX_KLASSE.KL_ID = T_KLASSE.KL_ID
                AND T_KLASSE.KL_STATUS_ID = 491   -- d.h. TS_CODE.CODE_UP_BEZEICHNUNG = 'AKTIV'
            

                AND VX_KLASSE.KL_KLASSENTYP_ID IN (742,743,1235,1926,2075,2076,2078,2079,2080,2081,2086,2103,2118,2119,2122,2152,2252,2308,2416)
        

                AND VX_PERSON.PER_NP = 1   -- Natürliche Person
                AND LEN(LTRIM(RTRIM(VX_PERSON.PER_VORNAME))) > 0        -- TRIM() kann erst ab SQL Server 2017 verwendet werden
                AND LEN(LTRIM(RTRIM(VX_PERSON.PER_NAME))) > 0           -- TRIM() kann erst ab SQL Server 2017 verwendet werden
        
 AND VX_ZEITRAUM.zr_beginn <= CONVERT(DATETIME, '20.05.2023', 104) 
 AND VX_ZEITRAUM.zr_ende   >= CONVERT(DATETIME, '14.02.2023', 104) 
 AND VX_PERSON.per_man_id IN ( 15 ) 

                --AND VX_Person.PER_ID IN  (233777,233779)
        

问题

*一般建议在定义列列表时不要使用,但在我的例子中,, *在末尾添加到列列表,可以显着加快查询速度。(从 21 秒减少到 2 秒)

实际执行计划中没有缺失索引建议。

, *我认为这与在语句中使用时返回的特定列有关,这些列可能包含在查询优化器认为有用的索引中,但我不确定如何查明这些列。

  1. 为了说服 SQL Server 运行不包含, *列列表的执行不佳的语句,使用与包含列列表中的附加项的性能语句类似的计划,我必须创建哪些索引?, *

  2. 我是否必须分析良好执行计划中使用的所有索引并创建缩减索引(省略某些列)以便查询优化器考虑对语句使用类似的良好, *执行计划而不需要额外的?


根据建议尝试解决方案

  1. OPTION (MIN_GRANT_PERCENT = 10, MAX_GRANT_PERCENT = 15)

    应用上述解决方案仅提供了大约 1 小时的临时性能提升。之后查询恢复到错误的执行计划。我不知道为什么...

  2. 数据库兼容级别

    ,*使用以下命令将数据库的兼容级别向下更改为 110 (SQL Server 2012),导致上述查询的性能不断提高,而无需在列列表中添加。

    USE [master]
    GO
    ALTER DATABASE [ECOWEBBSP] SET COMPATIBILITY_LEVEL = 110
    GO
    

    兼容级别为 110 的查询执行计划表明,查询优化器在检索数据时选择了一种完全不同的方法,并且在分配正确的内存量 (110 MB) 方面没有任何问题。

跟进问题

将兼容级别设置为 110 是我唯一的选择吗?

额外反馈

Erik 的回答中提到的Ominous Function是由视图中的fi_kla_is_abschlussklasse列触发的。基础表在检索数据时调用标量值函数。该函数本身返回 0 或 1,具体取决于学生是在毕业班 (1) 还是不在毕业班 (0)。VX_KLASSE_ZEITRAUM.KLZ_IS_ABSCHLUSSKLASSEECOLST.VX_KLASSE_ZEITRAUM

但是,在兼容级别设置为 110 (SQL Server 2012) 的情况下运行时,该函数似乎对查询持续时间的影响不大。有关详细信息,请参阅兼容级别为 110 的查询执行计划。

sql-server
  • 1 1 个回答
  • 1149 Views

1 个回答

  • Voted
  1. Best Answer
    Erik Darling
    2023-02-17T07:07:44+08:002023-02-17T07:07:44+08:00

    虽然这两个查询计划有很多差异,但您在较慢的计划中遇到的问题主要发生在溢出操作中,因为内存授予不足:

    坚果

    至少还有一次泄漏,但影响较小。

    更快的计划不会溢出的原因是因为它获得了更高的内存授予,SQL Server 根据行数和通过内存消耗运算符(如 Sorts 和 Hashes)的每行的估计大小来估计。

    这是内存授予信息:

    坚果

    在这种复杂的查询中很难获得准确的基数估计,但您可以尝试:

    • 更新统计数据
    • 使用旧版 CE:OPTION(QUERYTRACEON 9481)
    • 使用#temp 表分解查询
    • 使用 MIN_GRANT_PERCENT 提示获得更高的内存授予

    可能值得注意的是,您有一个标量 UDF 抑制此查询的并行性,以及几个可能导致估计值丢失的非 SARGable 谓词。

    功能:

    坚果

    查询反模式:

    AND LEN(LTRIM(RTRIM(VX_PERSON.PER_VORNAME))) > 0
    AND LEN(LTRIM(RTRIM(VX_PERSON.PER_NAME))) > 0
    

    可以简化为寻找单个字符通配符:

    AND VX_PERSON.PER_VORNAME LIKE '_%'
    AND VX_PERSON.PER_NAME LIKE '_%'
    

    或者只是寻找非空字符串:

    AND VX_PERSON.PER_VORNAME <> ''
    AND VX_PERSON.PER_NAME <> ''
    
    • 12

相关问题

  • 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