我对SQL的性能有疑问。我将用伪代码说明我的问题。
我想知道哪种形式会更好,多少会更好?对每个页面加载的10个项目说。在.NET中。是快了很多?快一点? 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
答案 0 :(得分:11)
第二个选项肯定会更快,因为它是单个网络往返,以及单个SP呼叫。
答案 1 :(得分:2)
绝对是第二个,从快10倍到更快。
如果您使用id进行的任何操作都可以在设置操作中完成,那么您将获得比单独调用SP几倍的性能提升。
我经常有类似的过程:
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
这是基于集合的操作;而不是在proc中使用游标的过程方法,或者使用for循环来迭代调用具有单个id的过程。
答案 2 :(得分:1)
因为这不适合ocdecio回答的评论......
只是为了扩展它...在我看到的大多数系统中,网络流量是性能的限制因素(假设合理调整的数据库和前端代码并非绝对可怕)。即使您的Web服务器和数据库服务器位于同一台计算机上,如果您经常在两者之间来回调用,则进程间通信可能会成为一个限制因素。
答案 3 :(得分:0)
在每个页面加载时,还是第一次加载页面?我不想为ASP.NET页面中的每一个回发都这样做。
要更直接地回答您的问题,如果您能够通过发送多个ID获得多条记录,请执行此操作。如果您需要超过10个项目,则效率更高,可扩展性更高。
答案 4 :(得分:0)
这一切都取决于proc的编码方式,如果你在第二个proc中传入了10个项目,然后proc使用游标来获取那些行,那么第一个调用可能会更快
答案 5 :(得分:0)
第二个实际上要快多少取决于太多东西。与结果集的大小相比,网络开销可能无关紧要。
还有另一种选择(根据锁定行为应该更快),这是call all of them asynchronously - 然后当最长的页面完成时,您的页面可以有效地完成。显然,这需要一些额外的编码。
在此示例中,只有一个SP开销。我们假设SP返回客户端将分割/处理的单个行集或多个行集:
int[] ids; // array of ids
CallSQLStoredProc(ids) // stored procedure returns more than one row for each id
在此示例中,SP呼叫开销是单次呼叫的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个DB调用开销,但性能改进可能取决于SQL Server和网络的容量,以便并行化工作负载。此外,您还可以在页面构建过程中启动SQL Server的工作。
单个SP解决方案仍然可以胜出,特别是如果它可以使用UNION组装单个结果集,其中SQL Server可以并行化任务。但是,如果结果集具有单独的模式或UNION无法很好地执行,则多重SP异步解决方案可以将其击败(并且还可以利用在页面中执行其他工作的能力)。
答案 6 :(得分:0)
迭代任何事情都会导致更多的开销。迭代提高性能的情况并不多。
我的建议一直是避免编程中的两件事:
您总是会遇到两种情况都会使用的情况,但使用它们的次数越少,您的应用程序运行得越快越顺畅。
答案 7 :(得分:0)
如果您希望应用程序具有可伸缩性,则需要尽可能使用缓存。您应该只运行一次共享查询并将结果存储在缓存中。
至于您的查询,如果您没有在查询中为每个ID使用游标,那么只要网络延迟对您的操作产生有意义的影响,它就应该更快。如有疑问,请测量。当我实际在我的函数上实现计时以查看不同的事情花了多长时间时,我一直非常惊讶。
在.net System.Diagnostics.StopWatch是你的朋友:)。