单线程版本说明:
我决定通过将问题列表拆分成块并为每个程序创建一个线程来多线程化上述程序。
每个线程打开它自己的数据库连接并处理它自己的问题列表(在6个线程中的每一个上大约95个问题)。应用程序等待所有线程完成,然后聚合结果以进行显示。
令我惊讶的是,多线程版本大约在同一时间内运行,大约需要16秒而不是17秒。
问题:
为什么我没有看到在具有单独连接的单独线程上同时执行查询时所期望的性能增益?机器有8个处理器。
当SQL Server来自单个应用程序时,它们是否会同时处理查询,或者它(或.net本身)是否可以序列化它们?
可能会出现配置错误,导致速度变快,或者我是否只是将SQL Server推向计算限制?
当前配置:
Microsoft SQL Server Developer Edition 9.0.1406 RTM
操作系统:Windows Server 2003标准版
处理器:8
内存:4GB
答案 0 :(得分:3)
这只是一个黑暗的镜头,但我敢打赌你没有看到性能提升,因为他们在数据库中序列化由于共享资源(记录)的锁定。现在是小字体。
我认为您的C#代码实际上是正确的,并且您实际上确实启动了单独的线程并并行发出每个查询。没有冒犯,但我已经看到很多人提出这种说法,并且由于各种原因,代码实际上是在客户端串行的。您应该通过监视服务器(通过Profiler,或使用sys.dm_exec_requests和sys.dm_exec_sessions)来验证这一点。
此外,我假设您的查询具有相似的权重。也就是说,你没有一个持续15秒和5个100毫秒的线程。
您描述的症状缺乏更多细节,表明您在每个线程的开头都有一个写入操作,该操作对某些资源进行X锁定。第一个线程启动并锁定资源,其他5个等待。第一个线程完成,释放资源然后下一个抓取它,其他4个等待。因此,最后一个线程必须等待所有其他5的执行。通过查看sys.dm_exec_requests并监视阻止请求的内容,这将非常容易进行故障排除。
BTW你应该考虑使用Asynchronous Processing = true并依赖于像BeginExecuteReader这样的异步方法,在没有客户端线程开销的情况下并行执行命令。
答案 1 :(得分:0)
您的数据库有多大? 您的HDD / Raid /其他存储的速度有多快
也许你的数据库是I / O绑定的?
答案 2 :(得分:0)
我的第一个倾向是你试图解决线程的IO问题,这几乎不可行。 IO是IO,更多线程不会增加管道。您最好一次性下载所有问题及其答案,并使用多个线程在本地处理批处理。
话虽如此,您可能正在经历一些导致速度缓慢的数据库锁定。由于您正在讨论只读查询,请尝试在查询中使用with(nolock)提示,看看是否有帮助。
关于SQL服务器处理,我理解SQL Server将尝试尽可能多地同时处理多个连接(每个连接一次一个语句),直到配置允许的最大连接数。你遇到的问题几乎从来都不是线程问题,几乎总是锁定或IO问题。
答案 3 :(得分:0)
线程是否可能共享连接?你运行时是否验证了多个SPID(sp_who)?
答案 4 :(得分:0)
我在task_address上的sys.dm_os_workers,sys.dm_os_tasks和sys.dm_exec_requests上运行了一个连接查询,这里是结果(排除了一些不感兴趣/零值的字段,其他前缀为ex或os以解决歧义):
-COL_NAME- -Thread_1- -Thread_2- -Thread_3- -Thread_4-
task_state SUSPENDED SUSPENDED SUSPENDED SUSPENDED
context_switches_count 2 2 2 2
worker_address 0x3F87A0E8 0x5993E0E8 0x496C00E8 0x366FA0E8
is_in_polling_io_completion_routine 0 0 0 0
pending_io_count 0 0 0 0
pending_io_byte_count 0 0 0 0
pending_io_byte_average 0 0 0 0
wait_started_ms_ticks 1926478171 1926478187 1926478171 1926478187
wait_resumed_ms_ticks 1926478171 1926478187 1926478171 1926478187
task_bound_ms_ticks 1926478171 1926478171 1926478156 1926478171
worker_created_ms_ticks 1926137937 1923739218 1921736640 1926137890
locale 1033 1033 1033 1033
affinity 1 4 8 32
state SUSPENDED SUSPENDED SUSPENDED SUSPENDED
start_quantum 3074730327955210 3074730349757920 3074730321989030 3074730355017750
end_quantum 3074730334339210 3074730356141920 3074730328373030 3074730361401750
quantum_used 6725 11177 11336 6284
max_quantum 4 15 5 20
boost_count 999 999 999 999
tasks_processed_count 765 1939 1424 314
os.task_address 0x006E8A78 0x00AF12E8 0x00B84C58 0x00D2CB68
memory_object_address 0x3F87A040 0x5993E040 0x496C0040 0x366FA040
thread_address 0x7FF08E38 0x7FF8CE38 0x7FF0FE38 0x7FF92E38
signal_worker_address 0x4D7DC0E8 0x571360E8 0x2F8560E8 0x4A9B40E8
scheduler_address 0x006EC040 0x00AF4040 0x00B88040 0x00E40040
os.request_id 0 0 0 0
start_time 2009-05-26 19:39 39:43.2 39:43.2 39:43.2
ex.status suspended suspended suspended suspended
command SELECT SELECT SELECT SELECT
sql_handle 0x020000009355F1004BDC90A51664F9174D245A966E276C61 0x020000009355F1004D8095D234D39F77117E1BBBF8108B26 0x020000009355F100FC902C84A97133874FBE4CA6614C80E5 0x020000009355F100FC902C84A97133874FBE4CA6614C80E5
statement_start_offset 94 94 94 94
statement_end_offset -1 -1 -1 -1
plan_handle 0x060007009355F100B821C414000000000000000000000000 0x060007009355F100B8811331000000000000000000000000 0x060007009355F100B801B259000000000000000000000000 0x060007009355F100B801B259000000000000000000000000
database_id 7 7 7 7
user_id 1 1 1 1
connection_id BABF5455-409B-4F4C-9BA5-B53B35B11062 A2BBCACF-D227-466A-AB08-6EBB56F34FF2 D330EDFE-D49B-4148-B7C5-8D26FE276D30 649F0EC5-CB97-4B37-8D4E-85761847B403
blocking_session_id 0 0 0 0
wait_type CXPACKET CXPACKET CXPACKET CXPACKET
wait_time 46 31 46 31
ex.last_wait_type CXPACKET CXPACKET CXPACKET CXPACKET
wait_resource
open_transaction_count 0 0 0 0
open_resultset_count 1 1 1 1
transaction_id 3052202 3052211 3052196 3052216
context_info 0x 0x 0x 0x
percent_complete 0 0 0 0
estimated_completion_time 0 0 0 0
cpu_time 0 0 0 0
total_elapsed_time 54 41 65 39
reads 0 0 0 0
writes 0 0 0 0
logical_reads 78745 123090 78672 111966
text_size 2147483647 2147483647 2147483647 2147483647
arithabort 0 0 0 0
transaction_isolation_level 2 2 2 2
lock_timeout -1 -1 -1 -1
deadlock_priority 0 0 0 0
row_count 6 0 1 1
prev_error 0 0 0 0
nest_level 2 2 2 2
granted_query_memory 512 512 512 512
所有查询的查询计划预测器显示一对节点,0%表示选择,100%表示聚簇索引搜索。
编辑:我遗漏的字段和值(所有4个线程都相同,但context_switch_count除外):exec_context_id(0), host_address(0x00000000), status(0), is_preemptive(0), is_fiber(0), is_sick(0), is_in_cc_exception(0), is_fatal_exception(0), is_inside_catch(0), context_switch_count(3-89078), exception_num(0), exception_Severity(0), exception_address(0x00000000), return_code(0), fiber_address(NULL), language(us_english), date_format(mdy), date_first(7), quoted_identifier(1), ansi_defaults(0), ansi_warnings(1), ansi_padding(1), ansi_nulls(1), concat_null_yields_null(1), executing_managed_code(0)
答案 5 :(得分:0)
您可以在进程运行时查看任务管理器。如果它显示100%的CPU使用率,那么它的CPU绑定。否则它的IO绑定。
对于超线程,50%的CPU使用率大致相当于100%的使用率!
哇我没想到这个帖子多大了。我想将其他人的回应留给他人总是好的。