Optimizing the PDF Export of Huge Reports in Sql Reporting Services 2005 - sql-server

First off I understand that it is a horrible idea to run extremely large/long running reports. I am aware that Microsoft has a rule of thumb stating that a SSRS report should take no longer than 30 seconds to execute. However sometimes gargantuan reports are a preferred evil due to external forces such complying with state laws.
At my place of employment, we have an asp.net (2.0) app that we have migrated from Crystal Reports to SSRS. Due to the large user base and complex reporting UI requirements we have a set of screens that accepts user inputted parameters and creates schedules to be run over night. Since the application supports multiple reporting frameworks we do not use the scheduling/snapshot facilities of SSRS. All of the reports in the system are generated by a scheduled console app which takes user entered parameters and generates the reports with the corresponding reporting solutions the reports were created with. In the case of SSRS reports, the console app generates the SSRS reports and exports them as PDFs via the SSRS web service API.
So far SSRS has been much easier to deal with than Crystal with the exception of a certain 25,000 page report that we have recently converted from crystal reports to SSRS. The SSRS server is a 64bit 2003 server with 32 gigs of ram running SSRS 2005. All of our smaller reports work fantastically, but we are having trouble with our larger reports such as this one. Unfortunately, we can't seem to generate the aforemention report through the web service API. The following error occurs roughly 30-35 minutes into the generation/export:
Exception Message: The underlying connection was closed: An unexpected error occurred on a receive.
The web service call is something I'm sure you all have seen before:
data = rs.Render(this.ReportPath, this.ExportFormat, null, deviceInfo,
selectedParameters, null, null, out encoding, out mimeType, out usedParameters,
out warnings, out streamIds);
The odd thing is that this report will run/render/export if the report is run directly on the reporting server using the report manager. The proc that produces the data for the report runs for about 5 minutes. The report renders in SSRS native format in the browser/viewer after about 12 minutes. Exporting to pdf through the browser/viewer in the report manager takes an additional 55 minutes. This works reliably and it produces a whopping 1.03gb pdf.
Here are some of the more obvious things I've tried to get the report working via the web service API:
set the HttpRuntime ExecutionTimeout
value to 3 hours on the report
server
disabled http keep alives on the report server
increased the script timeout on the report server
set the report to never time out on the server
set the report timeout to several hours on the client call
From the tweaks I have tried, I am fairly comfortable saying that any timeout issues have been eliminated.
Based off of my research of the error message, I believe that the web service API does not send chunked responses by default. This means that it tries to send all 1.3gb over the wire in one response. At a certain point, IIS throws in the towel. Unfortunately the API abstracts away web service configuration so I can't seem to find a way to enable response chunking.
Does anyone know of anyway to reduce/optimize the PDF export phase and or the size of the PDF without lowering the total page count?
Is there a way to turn on response chunking for SSRS?
Does anyone else have any other theories as to why this runs on the server but not through the API?
EDIT: After reading kcrumley's post I began to take a look at the average page size by taking file size / page count. Interestingly enough on smaller reports the math works out so that each page is roughly 5K. Interestingly, when the report gets larger this "average" increases. An 8000 page report for example is averaging over 40K/page. Very odd. I will also add that the number of records per page is set except for the last page in each grouping, so it's not a case where some pages have more records than another.

We narrowed down the large PDF exports from SSRS and found 2 main culprits
1) Unless images are JPG or PNG colour type 3, they are expanded to BMP's See here
2) Unless you configure SSRS to behave otherwise (not recommended), then SSRS will embed fonts or font subsets into the PDF, unless they are one of the 5 'standard' PDF fonts.
Although none of the standard fonts (other than Symbol I guess) are installed on most Windows OS's out of the box, we've found that if you use Times New Roman, Courier New, or Arial then forward and reverse font substitution will take place.
The easiest way to convert your RDL's is to view them as XML and search and replace the FontFamily tags.
If you have to use a non standard font, then, you can still minimize the damage:
Use as few fonts as you can. Search through the RDL XML to make sure there aren't any redundant fonts.
Use TTF fonts if you use different sizes of the font.
Try not to mix normal, bold and italic variants of the font, else it will be embedded multiple times.

Does anyone know of anyway to
reduce/optimize the PDF export phase
and or the size of the PDF without
lowering the total page count?
I have a few ideas and questions:
1. Is this a graphics-heavy report? If not, do you have tables that start out as text but are converted into a graphic by the SSRS PDF renderer (check if you can select the text in the PDF)? 41K per page might be more than it should be, or it might not, depending on how information-dense your report is. But we've had cases where we had minor issues with a report's layout, like having a table bleed into the page's margins, that resulted in the SSRS PDF renderer "throwing up its hands" and rendering the table as an image instead of as text. Obviously, the fewer graphics in your report, the smaller your file size will be.
2. Is there a way that you could easily break the report into pieces? E.g., if it's a 10-location report, where Location 1 is followed by Location 2, etc., on your final report, could you run the Location 1 portion independent of the Location 2 portion, etc.? If so, you could join the 10 sub-reports into one final PDF using PDFSharp after you've received them all. This leads to some difficulties with page numbering, but nothing insurmountable.
3. Does anyone else have any other
theories as to why this runs on the
server but not through the API?
My guess would be the sheer size of the report. I don't remember everything about what's an IIS setting and what's SSRS-specific, but there might be some overall IIS settings (maybe in Metabase.xml) that you would have to be updated to even allow that much data to pass through.
You could isolate the question of whether the time is the problem by taking one of your working reports and building in a long wait time in your stored procedures with WAITFOR (assuming SQL Server for your DBMS).
Not solutions, per se, but ideas. Hope it helps.

Obviously, its a huge report, in fact it's closer to a 1.3 GB database, than a report.
Have you thought of finding a way to split it into multiple pieces and then combine them together? (use one of several different ways to combine PDFs listed on this site.)

Related

SSRS Random Error - There is no data for field at

We have a process that generates around 20,000 PDFs using SSRS as the backend.
The mechanism used to generate these is the Report Execution 2005 API endpoint
We have just performed a run where occasionally a PDF would be generated missing some data, or the header or the body or the footer.
The break down of that was around 12,000 generated correctly, 1000 blank, 7000 data incorrect.
There doesn't seem to be a rhyme or reason for this, no pattern in the data or timings. In the logs we can see the following:
We log all parameters used to execute these reports in a DB, so using this we went and re-run that report with the same parameters and it ran fine. We then went and took 100 of the random errored ones, ran them manually and they all worked fine.
My only straw left to grasp at is there is some caching or SSRS deep issue that is causing this.
If anyone has seen something similar or has an opinion on where to check next, would be much appreciated.

SSRS report returns different results in Chrome vs IE/Edge/Visual Studio

I'm having some issues with a report deployed to an SSRS 2016 server.
When the report is run in IE, Edge or previewed in VS it returns the correct result (some sales data for the current month), but when the same report is run in Chrome it returns values for the whole year.
I've searched for thoroughly for a resolution but was unable to find anything. I did find a few posts here and elsewhere regarding compatability issues between Chrome and SSRS 2016, but the resolutions (using various Chrome extensions), did not work. Using an extension is not really the solution that I want, as I'm more concerned about users viewing reports in Chrome and seeing incorrect results.
Additional info:
+This is a report I have inherited and did not design.
+Report has a number of parameters, some hidden, some not.
+Report contains 18 datasets.
+There are some textboxes with actions in the report, each of which execute the report with different parameters (eg last quarter, YTD).
+When certain actions are executed, the report returns the below error. This only happens when using Chrome.
An error has occurred during report processing. (rsProcessingAborted)
Cannot read the next data row for the dataset ConversionRates. >(rsErrorReadingNextDataRow)
For more information about this error navigate to the report server on the >local server machine, or enable remote errors
+The dataset described in the above error is not the same every time the report is run.
What I've tried already:
+Various Chrome extensions (more as a test than a solution), these made no difference.
+Searching this site / Google for suggestions but to no avail.
What I would like to achieve:
I would like to know how I can ensure that the correct results can be
returned in Chrome for any user, without having to perform any action
on each user's machine.
I realize this is not much to go on, but I'm hoping someone else has encountered the same error. I suspect it's something to do with rendering in Chrome but I can't figure it out, so any suggestions at all would be greatly appreciated.
Thanks v much

SSRS auto refresh (AutoRefresh) only partially works on particular clients

We've been successfully using SSRS auto refresh (SQL Server 2008R2) on a variety of clients over the years and never had any problems. Various combinations of Chrome and IE on various OSs (windows XP, 7 and 10) have all been fine. We've just deployed a new report to run in full screen mode on TV screens, and it seems to be PARTIALLY refreshing. The Globals!ExecutionTime displays accurately, but new rows (INSERTs in the source data) in the report's tablix do not show up until the report is manually refreshed. Even more oddly, UPDATEs to the source data seem to make it through the auto refresh process. The problem only seems to occur on these particular clients.
We've set up a report history to help monitor this problem, and it works as expected. In fact it highlights the inconsistency, where newer information is captured in snapshots that were run earlier that the screen autorefresh.
The report execution logs are recording exactly the executions we'd expect to see. The data is just not making it onto the screen.
The report's processing options are:
Always run this report with the most recent data,
Do not cache temporary copies of this report
Any suggestions greatly appreciated :-)
Well we eventually resolved it. The problem turned out to be not exactly as described above. It seems to have been due to unusual combination of several cascading parameters, and a rapidly changing underlying dataset. What would happen, is that:
The SQL behind the cascading parameters would be executed on autorefresh in order to populate each parameter's default values.
During or shortly after this, the source data would change.
Next the final dataset SQL would be executed using the now out-of-date parameter values, and bring back the wrong results.
The solution was to remove four of the five cascading parameters from the report (and the underlying stored procedure). The stored procedure had initially been intended to be widely used and that was the reason for needing all the parameters. Turns out though that it was only used by the report, so as luck would have it we were able to simplify the process.

SSRS 2008 R2 - Excel output not formatting to page size

I have a batch of reports that are set up to print very nicely in landscape on A4 page. But when I set the default format to Excel, the resulting spreadsheet, when printed without changing anything in the print setup, is wider than an A4 page so of course it gets broken up over mulitple pages (i.e: each page is 2 pages wide rather than 1)
Most of our users just want to print these as soon as they arrive via email (but they still want Excel format so they can re-sort, cut and paste, etc) so how can I make Excel keep the print format defined in the report in SSRS so the users don't have to mess about with print settings? (These are daily reports so this is driving our users mad as some of them may get 4 or 5 reports!)
Do I have to use an Excel template (can this even be done?) or is there a way to acheieve what I want via SSRS?
TIA for any help....
Mike
The short answer is that you can't exactly do what you want with the Excel renderer. Some workarounds that come to mind:
Filling an Excel template with data might be an option, but is more of a job for SSIS, not reporting services.
Send the report in PDF for printing, and if needed in Excel as well.
Re-layout the report so it plays well with the default printing of Excel. This won't be very pretty, you'd need to either make columns much smaller (and perhaps rotate headers using the WritingMode property) or turn columns into row groups somehow.
(hack warning!) create an Excel macro or something alike for your users, that does some printing-quick-fixes.
Some background
Unfortunately SSRS gives you only a small bit of control over how the report is rendered in the various rendering extensions. There's this MSDN page on rendering extensions (additional emphasis mine) with some useful info:
Soft page-break renderers: Soft page-break renderers maintain the report layout and formatting. The resulting file is optimized for screen-based viewing and delivery, such as on a Web page. The available soft page-break renderers are: Microsoft Excel, Microsoft Word, Web archive (MHTML), and HTML.
Hard page-break renderers: Hard page-break renderers maintain the report layout and formatting. The resulting file is optimized for a consistent printing experience, or to view the report online in a book format. The available hard page-break renderers are supported: TIFF and PDF.
So, if you want to optimize for printing experience, you should probably use the PDF export. You can then play around with the page size and margins to fit as much info as possible on a page, and let the client program (probably Adobe Reader) worry about printing it nicely.

How can I find why some classic asp pages randomly take a real long time to execute?

I'm working on a rather large classic asp / SQL Server application.
A new version was rolled out a few months ago with a lot of new features, and I must have a very nasty bug somewhere : some very basic pages randomly take a very long time to execute.
A few clues :
It isn't the database : when I run the query profiler, it doesn't detect any long running query
When I launch IIS Diagnostic tools, reqviewer shows that the request is in state "processing"
This can happen on ANY page
I can't reproduce it easily, it's completely random.
To have an idea of "a very long time" : this morning I had a page take more than 5 minutes to execute, when it normaly should be returned to the client in less than 100 ms.
The application can handle rather large upload and download of files (up to 2 gb in size). This is also handled with a classic asp script, using SoftArtisan FileUp. Don't think it can cause the problem though, we've had these uploads for quite a while now.
I've had the problem on two separate servers (in two separate locations, with different sets of data). One is running the application with good ol' SQL Server 2000 and the other runs SQL Server 2005. The web server is IIS 6 in both cases.
Any idea what the problem is or on how to solve that kind of problem ?
Thanks.
Sebastien
Edit :
The problem came from memory fragmentation. Some asp pages were used to download files from the server. File sizes could go from a few kb to more than 2 gb. These variations in size induced memory fragmentation. The asp pages could also take quite some time to execute (the time for the user to download the pages minus what is put in cache at IIS's level), which is not really standard for server pages that should execute quickly.
This is what I did to improve things :
Put all the download logic in a single asp page with session turned off
That allowed me to put that asp page in a specific pool that could be recycled every so often (download would now disturb the rest of the application no more)
Turn on LFH (Low Fragmention Heap), which is not by default on Windows 2003, in order to reduce memory fragmentation
References for LFH :
http://msdn.microsoft.com/en-us/library/aa366750(v=vs.85).aspx
Link (there is a dll there that you can use to turn on LFH, but the article is in French. You'll have to learn our beautiful language now!)
I noticed the same thing on a classic ASP + ajax application that I worked on. Using Timer, I timed the page load to be 153 milliseconds but in the firebug waterfall chart it randomly says 3.5 seconds. The Timer output is on the response and the waterfall chart claims that it's Firefox waiting for a response from the server. Because the waterfall chart also shows the response, I can compare the waterfall chart to the timer and there's a huge discrepancy 'every so often'
Can you establish whether this is a problem for all pages or a common subset of pages?
If a subset examine what these pages have in common, for example they all use a specific COM dll, that other pages don't.
Does this problem affect multiple clients or just a few?
IOW is there an issue with a specific browser OS version.
Is this public or intranet?
Can you reproduce the problem from a client you own?
Is there any chance there are some full-text search queries going on SQL Server?
Because if so, and if SQL Server has no access to internet, it may cause a 45-second delay every few hours or so when it tries to check the certifications (though this does not apply to SQL Server 2000).
For a detailed explanation of what I'm referring to, read this.
Are any other apps running on your web server? If so, is your problematic in the same app pool as any of them? If so, try creating a dedicated app pool for it. Maybe one of the other apps is having a problem and is adversely affecting yours.
One thing to watch out for is if you have server side debugging turned on in IIS, the web server will run in single threaded mode.
So if you try to load a page, and someone else has hit that url at the same time, you will be queued up behind them. It will seem like pages take a long time to load, but its simply because the server is doling out page requests in a single file line and sometimes you aren't at the front of the line.
You may have turned this on for debugging and forgot to turn it off for production.

Resources