Performance gains running your queries in parallel
Hey All,
Got back from PDC a few days ago and now I am sitting at SeaTac airport waiting for my flight to Barcelona for TechEd EMEA. I figured it was time to start sharing some of the stuff I showed at PDC...
Today we are going to talk about the performance gains you can see when you run you queries in parallel. The two points I am always trying to drive home are around partitioning and running your operations in parallel.
I have been talking about this for about 9 months and I figured for PDC it would be better to demonstrate what I have been talking about.
Inside a test Authority I created 26 containers - one for each letter in the alphabet. I then loaded up 200,000 fictitious users and partitioned the data based upon the first character of the user's last name. No big deal - what kind of developer doesn't have a fictitious name generator :)
I then wrote a quick winform app show below
The app lets you enter in a user's first name and the number of worker threads. When you click begin it will use the thread pool and queue up 26 queries (one for each letter in the alphabet) and when all queries have completed, it will show the number of records returned and the time it took...
Lets give it a spin...
Searching for the first name of Jacob across 26 containers returns 9495 entities in 7.72 seconds...Not too shabby. The reason that the thread lower bound is 4 is because the I ran this from my home machine which has 2 dual core processors and the lowest you can set the Max Worker Threads to is equal to the number of processors (the OS views each core as a processor). I intentionally ran this from home to insure I wasn't on the Microsoft network. I have cable Internet from Comcast.
Now lets try with 10 threads...
Not bad 9495 entities in 4.71 seconds...Let bump it up to 26 threads so all queries get processed concurrently...
9495 records in 2.94 seconds....WOW!!!
If we think about what just happened we launched 26 queries in parallel. Chances are each query got processed by a separate front-end server. Since I partitioned my data across 26 containers, chances are each container ended up on a separate back-end node. That means I most likely had 26 different front end servers querying 26 different back-end database nodes and returning the results (not just the counts, but the actual entities) to my test application. When all threads had completed the app aggregated all the results into a List<Person> and displayed the count. I keep saying chances are since I haven't looked to see on what nodes my containers ended up on. Similarly I don't know what front-ends processed my request.
Hopefully this little demonstration has conveyed how partitioning and multithreading your SDS calls can really provide some major performance benefits.
Let me know if you have any questions or comments,
Dave