Thursday, September 3, 2009

A good day

Today was a good day. I love walking out of work having solved more problems than I caused.

Today there were two staring me in the face. First, my WPF client was timing out calling a long-running WCF method over NetTcpBinding. This is actually the second or third time this problem has reared its ugly head. I was calling the method asynchronously (client-side asynchronously), and I was hoping that would let me circumvent the timeouts like it does with traditional web services. No dice. Then I tried increasing the ReceiveTimeout, which several posts recommended (and which appears to have worked for the NetNamedPipesBinding call I'm making inside the service), but it still failed. In the end, Juval Lowy was my personal Jesus once again (if I run into him at PDC this year, I'm going to buy him a beer). I pulled Programming WCF off of the shelf and found the section that talked about session timeouts in the NetTcpBinding. It turns out that you need to enable ReliableMessaging (on both sides of the pipe, or you'll get a Contract mismatch error) and set the InactivityTimeout to override the idle timeout for NetTcp services. And since the long-running method was part of a big service contract that we used frequently, I decided to move the method to another service contract so the reliable messaging wouldn't add too much overhead. This was a big win for us, because this method kicks off an ETL package, reprocesses our cube, and pushes out all the report subscriptions.

The next problem we had was an OLAP-sourced report that's had terrible performance ever since we started accruing data snapshots in the cube. The report has two different measures that share two common dimensions, and then I have a third dimension that is only related to one of the two measures. The report is structured as a two-tier report with the two shared dimensions
on the top level and the third dimension as a drilldown into Measure Group 2. But the SSRS-generated MDX was a hot mess. For a long time, I thought it was the fact that it was trying to pull back Dimension 3 and Measure Group 1 in the same report and it was doing some kind of weird cross-join that was killing my performance. But a more astute cube jockey took a look at it and pointed out that it was trying to return back way too many rows. All of the measures have to be on the same axis in your cube, and my Measure Group 1 was returning a value for every Dimension 1/Dimension 2 combination. Result: 350,000 rows, and a memory spike in SSMS of 1 GB (yikes). So I sat down and figured out what rows I really needed and got it knocked down to about 30,000 rows and 200 MB.

Enough challenges for one day. Tomorrow is another full day.