SQL性能问题

4

我有一个关于SQL性能的问题。我将用伪代码说明我的问题。

我想知道哪种方法会更快,以及差距有多大?比如在.NET中,每个页面加载10个项目。它会快很多吗?还是稍微快一点?对于SQL来说没有明显的区别?

foreach(item in mylist) {
CallSQLStoredProc(item.id);
}

vs

int[] ids; // array of ids
CallSQLStoredProc(ids)  // stored procedure returns more than one row for each id
8个回答

11
第二个选项肯定更快,因为它只需要进行一次网络往返和一次服务提供者调用。

2

毫无疑问是第二个,速度大约快了10倍甚至更多。

如果您对ID进行的任何操作可以通过集合操作完成,那么与单独调用存储过程相比,您将获得数倍的性能提升。

我经常有像这样的存储过程:

create procedure proc ( @ids varchar(max) ) as
select * from users_tbl u
inner join spiltCSVs(@ids) c
  on c.id = u.id
--so on and so forth

这是一种基于集合的操作,与使用游标在过程中进行逐个调用过程或使用for循环迭代来调用具有单个ID的过程的过程方法相对。


你使用哪个数据库? 我正在寻找 SQL Server 中的“spiltCSVs”函数。 谷歌搜索“spiltCSVs”只返回了一个结果 :-) - Peter Gfader
这是一个实用函数,每个人根据需要编写。 - Tom Ritter

1

由于这个回答无法放在ocdecio的评论中...

只是为了扩展一下...在我看到的大多数系统中,网络流量是性能的限制因素(假设数据库已经调优并且前端代码不是绝对可怕的)。即使您的Web服务器和数据库服务器在同一台机器上,如果两者之间频繁地来回调用,则进程间通信也可能成为限制因素。


0
每次页面加载时,或者第一次加载页面时?我不想在 ASP.NET 页面的每个 postback 上都这样做。
更直接地回答你的问题,如果你能通过发送多个 ID 来获取多条记录,请这样做。这样更有效率,而且如果你需要超过 10 个项目,也更具可扩展性。

0

这完全取决于存储过程的编码方式,如果你在第二个存储过程中传入了10个项目,并且该存储过程使用游标来获取这些行,则第一次调用可能会更快。


0

无论迭代什么,都会导致更多的开销。很少有情况下迭代会提高性能。

我的建议一直是在编程中避免两件事:

  1. if then else语句
  2. 迭代

你总会遇到需要使用它们的情况,但是你使用得越少,你的应用程序就越有可能运行得更快、更顺畅。


0

如果您想在应用程序中实现可伸缩性,您需要尽可能多地使用缓存。 您应该仅运行任何共享查询一次,并将结果存储在缓存中。

至于您的查询,只要您没有在每个ID的查询中使用游标,它应该更快,前提是网络延迟对您的操作产生了实质影响。 如果不确定,请进行测量。 我曾经非常惊讶,当我实际上在我的函数上实施计时以查看不同事物所需的时间时。

在.NET中,System.Diagnostics.StopWatch是您的好朋友:)


0

第二个方法会快多少取决于很多因素,网络开销可能相比结果集的大小微不足道。

还有另一种选择(根据锁定行为应该比前两者更快),即异步调用它们全部 - 这样你的页面可以在最长时间完成时有效地完成。显然,这需要额外的编码。

在这个例子中,只有一个SP开销。 我们假设SP返回单个行集或多个行集:

int[] ids; // array of ids
CallSQLStoredProc(ids)  // stored procedure returns more than one row for each id

在这个例子中,存储过程调用的开销是单次调用的n倍。而且这些调用是串行化的。
foreach(item in mylist) {
    CallSQLStoredProc(item.id);
}

在第三种选择中:
foreach(item in mylist) {
    StartSQLStoredProc(item.id);
}

// Continue building the page until you reach a point where you absolutely have to have the data

wait();

这仍然具有n个数据库调用开销,但性能的提升取决于SQL Server和网络的容量以便并行处理工作负载。此外,您还可以在页面构建时启动SQL Server。

单个SP解决方案仍然可以胜出,特别是如果它可以使用UNION组装单个结果集,而SQL Server可以并行化任务。然而,如果结果集具有不同的模式或UNION无法执行良好,则多个SP异步解决方案可以击败它(并且还可以利用在页面中执行其他工作的能力)。


如果可以异步完成,那么可以编写成由数据库引擎并行化执行。在这种情况下,单个调用仍将更快。单个调用始终会更快。 - jennykwan
不幸的是,DB中的SP中的单独批次没有并行化。如果您可以同时从数据库流式传输10个不同的大型流,则必须构建10个行集然后返回它们的单个调用不能保证更快。我将更新答案以进行演示。 - Cade Roux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接