2

在一个应用程序中,我有 2000 个帐户。第一个账户包含 10000 个客户,这是一个账户的最大限制。用户可以从第一个账户中选择客户,然后选择一些账户将选定的客户复制到选定的账户。所以可能的最大值是 1999 个帐户和 10000 个客户。

目前,我正在遍历 Account 列表并在客户端应用程序的每次迭代中调用存储过程。在每次迭代中,将一个 Account Id 和一个包含客户端 ID 列表的表值参数传递给 SP。使用 500 个帐户和 10000 个客户端进行测试时,需要 25 分钟、34 秒和 543 毫秒。在 SP 中的某个时刻,我正在使用以下代码 –

INSERT INTO Client
SELECT AccountId, CId, Code, Name, Email FROM Client
WHERE Client.Id IN(SELECT Id FROM @clientIdList)

其中@clientIdList是包含 10000 个客户 ID 的表类型变量。

问题是,每次迭代后,都会将 10000 个新的客户端数据添加到客户端表中。因此,对于每次迭代,此INSERT操作在下一次迭代中将花费更长的时间。谷歌搜索一些 SP 性能提示我开始知道该IN子句被认为有些邪恶,大多数人建议使用它INNER JOIN。所以我把上面的代码改成了——

INSERT INTO Client
SELECT c.AccountId, c.CId, c.Code, c.Name, c.Email FROM Client AS c
INNER JOIN @clientIdList AS cil
ON c.Id = cil.Id

现在需要 25 分 17 秒和 407 毫秒。没有什么令人兴奋的,真的!

我是存储过程领域的新手。那么,有了这么多的数据,它应该需要这么长时间吗?对于给定的场景,我应该考虑哪一个,IN或者INNER JOIN?欢迎提出建议和性能提示。谢谢。

4

1 回答 1

1

如果不了解您的存储过程的更多信息,就很难准确判断发生了什么。

我建议检查执行计划。为此,请打开 SQL Server Management Studio。在一个新的查询窗口中调用您的存储过程并传入任何相关参数。

在执行此操作之前,请转到 Query 菜单并选择 Client Side Statistics 和 Actual Execution Plan 菜单项。

现在运行您的查询。

25 分钟后回来,底部应该有 3 或 4 个选项卡(取决于它是否返回数据。) 1 个选项卡用于结果,1 个选项卡用于消息,1 个选项卡用于客户端统计信息和 1 个选项卡为执行计划。

客户端统计选项卡可用于查看您所做的更改是否会影响性能(它会保留您上次运行的几次以向您展示它在这些方面的表现如何。)

更有趣的选项卡是执行计划选项卡。看看这个,它应该看起来像这样: 在此处输入图像描述

在这里它告诉我我的查询能够在我的所有表上使用主键索引。您想查看整个表扫描(因为这意味着它没有使用索引。)另外,如果我的查询不是那么简单并且花费了很长时间,并且没有使用索引,那么在“查询 1”下方将是绿色文本,说明“缺少索引”或类似的内容。它会告诉您需要创建的索引以提高性能。

另请注意,它会以百分比形式告诉您每个查询花费了多少。我有一个查询,所以很明显它花了 100% 的时间。但是,如果您的存储过程中有 5 个查询,其中一个占用了 80% 的时间,您可能需要先检查那个。

它还以百分比形式告诉您查询的每个部分花费了多少时间。这有助于尝试了解您的查询正在做什么。

通过这个,我猜你的存储过程还有其他问题,你可以问后续问题。

于 2013-02-24T14:18:26.743 回答