SQL Server 如何处理同时的读/写请求?

SQL Server 如何处理同时的读/写请求?

背景:

我们有一个大量使用 SQL Server 2008 数据库的应用程序。我们正在尝试优化此应用程序。它是单线程的,我们通过应用程序的日志记录/分析注意到,最大的瓶颈是数据库读取/写入。一些调用需要长达 100 毫秒的时间,这对我们来说太长了。除其他优化外,我们将其中一些调用拆分到单独的线程中。仅从这一变化来看,我们就看到了处理时间的大幅改善(代码几乎完全相同,只是一些代码被移到了不同​​的线程中)

问题:

假设在内存中运行代码所花费的时间可以忽略不计,我猜想在另一个线程中执行某些读取/写入不会带来任何性能提升。我觉得如果 SQL Server 只是对请求进行排队,读取/写入无论如何都无法并行进行,因此处理时间会相似。事实并非如此。

我想知道 SQL Server 如何处理来自不同线程的两个同时请求(读/写的任何组合)。它能以某种方式同时执行它们吗?

总而言之,我假设相继调用 Query1 + Query2 的总时间与同时调用 Query1 + Query2 的总时间相似。

这是在双核服务器上运行的。

答案1

SQL Server 是一个多用户数据库。它主要用于处理多个同时发生的请求。

理想情况下,两个查询在串行执行时将采用 A + B,而在同时执行时将采用 MAX(A, B)。

为了防止读取或写入损坏的数据,SQL Server 使用交易锁定除此之外,应用程序可能还会管理并发性(乐观的, 例如)。

答案2

我认为 David B 给出了一个很好的答案,但我只想在这里通过一个例子来稍微扩展一下。

假设您的数据库中有两个表,Table_A 和 Table_B。服务器有多个处理器。此外,磁盘子系统将每个表放在单独的驱动器/LUN/主轴上(无论正确的术语是什么,我都不是硬件专家)。此外,服务器有多个 NIC 卡。

如果两个用户都访问数据库,一个用户想要写入 Table_A,而另一个用户想要从 Table_B 读取,那么希望您能够看到请求如何同时在不同的网卡上进入,由不同的 CPU/核心同时处理,并且 IO 活动如何同时在不同的磁盘上发生。

现在,在现实世界中,事情很少这么简单。通常,根据硬件和应用程序的使用方式,您会在一个或多个领域遇到瓶颈。此外,如果两个用户都试图访问同一个表中的相同行,则可能会导致资源瓶颈。因此,在现实生活中,有些人会花费大量时间试图找出哪些资源导致了应用程序的瓶颈,并消除这些瓶颈。但至少,通常存在一些可以并行处理事物的区域。

答案3

您的问题暗示在改进之前,SQL 访问是连续的,即后续查询在同一个连接上、同一个代码线程中一个接一个地执行。

将逻辑移到单独的线程将产生两个不同的效果:首先,你的代码不再需要等待每个查询完成后再继续,其次,SQL 查询将并行化(在一定程度上),从而允许 SQL 服务器优化数据文件访问 - 这比您的代码要好得多。

假设代码不仅仅包含纯 SQL 调用,前者的影响可能与后者一样大。

相关内容