sql-server - SQL Server并发访问

标签 sql-server performance

当sql server收到两个查询(SELECT * From_Same_Table)时,恰好同时,并且如果您的服务器具有多个处理器,sql server可以同时检索数据吗?

我试图了解如果便宜的select语句在0.01秒内完成,并且1000个用户恰好同时运行相同的查询,将会发生什么情况。我认为如果服务器具有四个处理器,SQL Server将在0.01秒内为前四个用户服务,而在0.02秒内为接下来的四个用户服务,将会发生什么情况。

这是否接近实际发生的情况?

我想我将尝试使用某种代码和记录器进行测试,或者可能会有可靠的测试工具来进行测试。

谢谢

最佳答案

SQL Server中的每个批次(请求)都会创建一个任务。计划任务执行并由工作人员接任务。 worker 与线程非常相似。任务留在工作人员手中,直到完成为止,然后释放工作人员来承担其他任务。系统中的工作程序数量有限,由sp_configure 'max worker threads'配置。至少有256名 worker ,其中约35名是系统 worker 。工作人员需要一个调度程序才能运行,并且每个CPU内核只有一个调度程序。 worker 合作共享调度程序。

有些任务会产生子任务,例如并行查询。这些任务也排队等待执行,需要工作人员完成。产生子任务的任务只有在其产生的所有任务都完成之后才能完成。

还有一些用户操作驱动的系统任务,例如登录握手。当客户端打开新的连接时,握手和登录身份验证/授权由任务完成,这需要工作人员。

当有1000个请求到达服务器时,将创建1000个任务并将其排队等待执行。自由 worker 拿起任务并开始执行它们。当他们完成一个任务时,他们接下一个任务,直到由1000个请求创建的所有任务完成。

显示正在发生什么情况的DMV是:

  • sys.dm_os_tasks
  • sys.dm_os_workers
  • sys.dm_os_schedulers
  • sys.dm_exec_requests

  • 这些详细信息在SQL Server Batch or Task SchedulingSlava's blog中进行了描述。

    此外,一旦任务执行完毕,请求将被编译。编译将首先在内存中查找请求文本,然后搜索现有的已编译计划以查找具有相同计划的请求。您可以阅读我对Dynamically created SQL vs Parameters in SQL Server的回复,以更详细地了解这种情况的发生。另请参见Execution Plan Caching and Reuse。计划一旦创建,便会开始执行。像SELECT ... FROM table这样的查询将创建一个简单的计划,该计划只有几个运算符,这些运算符基本上会获取每一行并将其放入TDS流中返回给客户端。查询计划是一棵运算符树,查询总是通过循环查询树的根目录下一行来执行,直到根目录返回EOF。树下的查询运算符越来越具体,直到最底层的运算符将是对所选访问路径(优化器为满足查询所选择的索引或堆)的物理访问。参见SQL Statement Processing。索引访问将始终从缓冲池而不是从磁盘请求数据。当缓冲池中没有缓存所请求的页面时,将PAGEIOLATCH放在页面上,并将读取该页面的请求提交给IO子系统。对同一页面的后续请求将等待此IO完成,并且一旦该页面在缓冲池中,则需要该页面的所有其他查询将从缓冲池中获取该页面。当缓冲池需要空闲页面时,将清除未使用的页面,但是如果系统具有足够的RAM,则一旦加载该页面就永远不会将其收回。索引和堆扫描操作将请求预读,从而预计将请求页面链接链中当前页面之前的页面。预读受到索引连续片段的限制,这是索引碎片出现的时候,因为它减少了预读请求的大小,请参阅Understanding Pages and Extents

    查询执行的另一个维度是行的逻辑锁定。为了稳定起见,根据隔离模型的不同,读取可能会在读取的行上放置行锁或范围锁,以防止在查询遍历扫描时进行并发更新。在SNAPSHOT隔离级别下,查询根本不会请求锁定,而将使用版本标记来可能服务从版本存储中请求的数据(请参阅SQL Server 2005 Row Versioning-Based Transaction Isolation)。在READ UNCOMMITED隔离下(或使用nolock提示时),查询不请求对其读取的行进行锁定,但是如果发生并发更新(未提交的行被读取,同一行可能被读取两次或现有行),则读取不一致可能根本看不懂)。

    关于sql-server - SQL Server并发访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2043350/

    相关文章:

    sql - 单个 SQL 查询处理 NULL 和非 NULL 值

    SQL 比较正在更新的字段

    sql - 插入查询的性能调优

    c++ - 为什么这个 C 代码比这个 C++ 代码快?获取文件中的最大行

    language-agnostic - 所有语言 - 程序效率

    sql - 限制随机选择中的记录

    mysql - 如何根据选择查询的结果更新表?

    performance - Scala 中的 @inline 注解真的对性能有帮助吗?

    C# - 进行更快的 MySql 查询?

    c# - 如何向/从 SQL Server 存储过程发送和接收参数