【发布时间】:2019-04-29 06:49:18
【问题描述】:
我有一个查询(合同 订单之间的关系),我决定将其分成两部分(合同和订单),以便在另一个存储过程中重用。
当我在分手前运行代码时,运行大约需要 10 秒;但是,当我使用一个函数来获取合同时,然后首先将数据泵入临时表,然后加入其他部分需要 2m:30s - 为什么会有时间差异?
该函数运行时间不到一秒,并且只返回一行,即一份合约的详细信息(contract_id 是提供给函数的参数)。
查询中对性能影响最大的部分(ORDERS)最大的表有 410 万行并且连接到其他几个表;如果我只是使用特定过滤器单独运行订单子查询,即合同 ID,它运行时间不到一秒钟,并且恰好根据我正在测试的合同返回零记录(由于过滤类型它正在寻找的订单)。
根据以上信息,您认为函数最多 1 秒 + 获取订单最多 1 秒 + 汇总 = 最多 2 秒,而不是 2 分半钟!
我哪里出错了,我如何开始隔离时差问题?
我知道有人会告诉我粘贴代码,但肯定是数据库与索引的问题,也许与编译器在处理原始代码与分解代码时的执行方式有关。在发布我的整个代码之前,我是否可以查看代码的某个区域,因为我已经尝试了从合同临时表到订单子查询的 OUTER APPLY 与 LEFT JOIN 的变体,并且两者都给了我大致相同的结果。有什么想法吗?
【问题讨论】:
-
很有可能使用 Function 而不是 Proc 在逻辑中创建了一个游标。尝试打开“包括实际执行计划”设置并运行两个版本。如果你看到在函数中一次又一次地执行相同的代码,那么它就变成了一个光标。
-
我不是在使用,而是说如果我使用 1) 直接表连接将代码的变体粘贴到 proc 中,运行 proc 大约需要 10 秒,而 2) 当我运行 proc 时将函数泵入临时表,然后在 proc 中进一步将临时表连接到子查询,proc 需要 2:30。
-
这些信息不足以帮助您...该函数是inline TVF 还是multi-statement 函数? JOIN 是如何完成的?如果您可以很早地应用过滤器,这可能意味着只调用该函数几次,否则该函数可能会被调用很多行,然后就将其丢弃。尝试检查并理解执行计划......是的:我要告诉你:粘贴你的代码:-)
标签: tsql sql-server-2008