I've got a SQL 2008R2 report that runs 12,000 times a month. It averages 60-90 seconds per execution.
I've been using SQL for 12 years, but I just started this job 2-3 weeks ago, and am still trying to get my head around some of these SSRS performance problems. It goes without saying I've been re-indexing everything in order to help this report.
Here is a picture / dump of my execution log:
SELECT ReportPath, TimeDataRetrieval, TimeProcessing, TimeRendering, Source, [RowCount]
FROM ReportServer.dbo.ExecutionLog2
WHERE UserName = '_________' AND ReportAction = 'Render'
ORDER BY timeStart desc
http://accessadp.com/?attachment_id=562
ReportPath TimeDataRetrieval TimeProcessing TimeRendering Source RowCount
/CubeReports/Freight Allocation 2954 4402 2039 Live 2348
/RS Reports/Freight Allocation 39954 4087 2380 Live 2348
/RS Reports/Freight Allocation 37718 3948 1888 Live 2348
/RS Reports/Freight Allocation 39534 4317 1937 Live 2348
/CubeReports/Freight Allocation 3257 4206 2422 Live 2348
/RS Reports/Freight Allocation 37517 4164 2402 Live 2348
/RS Reports/Freight Allocation 36127 4151 1986 Live 2348
/RS Reports/Freight Allocation 36415 39888 2569 Live 19048
/RS Reports/Freight Allocation 37544 41644 2071 Live 19048
/RS Reports/Freight Allocation 37970 41003 2187 Live 19048
/RS Reports/Freight Allocation 38057 48085 1885 Live 19048
/CubeReports/Freight Allocation 3030 4558 2056 Live 2348
/CubeReports/Freight Allocation 3534 5232 2422 Live 2348
Please note, I do believe I know what the difference in 'RowCount' is. I had a subreport that was running a dataset (that wasn't important) and I removed it.
I thought that this was the reason for the increase in performance.. but I've double-checked and triple-checked that the subReports no longer have the other dataset (and this is refereced in the decrease in rowcount). Unfortunately, that didn't translate into a decrease in processing time.
I downloaded the report from 'RS Reports', and deployed it to 'CubeReports'.. and I didn't change anything else on this version of the report.
I run it with the same parameters.. and now the copy of the report 'CubeReports' literally runs 10x faster.
I just can't figure out WHY this is happening?
I REALLY need to find the solution and move it into production.
I've checked snapshots, history, execution caching.. none of that is turned on, it all looks like the default setting for both reports.. I've checked all the other options, and I just can't find anything that would explain this.
The only three options I see:
Report Builder 3.0 isn't 'compiling the report' as well as BIDs
does.
Having 3-4 people running the primary report at the same
time I'm doing the test is causing this problem. (We have 300
employees, I really can't test anywhere else, because people run
this all day every day).
Dropping the report and re-deploying the
report, and crossing my fingers that this is going to make it run
10x faster
Unfortunately, I've been able to duplicate the 10x speed increase consistently, I've ran it about 10 times each with the same parameters with the same result. Keep in mind, there is only 1 SSRS server, going against 1 database server. Same sprocs, same parameters.
10x worse performance in the production copy of this report.
10x better performance when I copy it to a new folder.
Primary ERP database is ~100gb, only 4 cores, only 16gb RAM. SSRS Server is on a VM, it is only 2 cores, only 8gb RAM.
There is one additional database that lives on the SSRS Server; it's actually a fairly large database- but not a TON of activity. The other database (Bartender) is only 9gb data / 3gb log.
You might have a problem with the two words folder name. Try in another folder with a space in it's name and check there.
Just my 2 cents... but i lived to see the holy "i" declared global.
I encountered a similar performance problem recently. Using SQL Server Profiler, I tracked it down to the exact same query executing. It would sometimes cause ~1000 times the reads as other queries. The differences appeared to be whether the query was called as SQL or through RPC.
Digging into this further, and by some trial and error, I found the key difference in my case was that the option for ARITHABORT was set differently for the different connections or users.
Unfortunately, I don't remember which setting was the fast one in my case. I wasn't getting a failed query, but the state of this option caused different execution plans to be used. Placing the statement SET ARITHABORT ON or SET ARITHABORT OFF at the beginning of my query brought everything into alignment. ARITHIGNORE and ANSI_WARNINGS are similar settings, so you might look at those as well.
I've discovered that the report that runs faster says Credentials used to run this report are not stored and the report that runs slow says Default report parameter values are missing. I'm going to go back and double-check my defaults on the parameters.
I DO have a discrepancy in the default parameters. I'm probably going to go forward with dropping the report and re-deploying it.
Related
I'm using Delphi 6 for developing windows application and have a stored procedure which returns around 17 million rows. It takes 3 to 4 minutes while returning data in SQL Server Management Studio.
And, I'm getting an "out of memory" exception while I'm trying to access the result dataset. I'm thinking that the sp.execute might to executed fully. Do I need to follow any steps to fix this or shall I use sleep() to fix this issue?
Delphi 6 can only compile 32 bit executables.
32 bit executables running on a 32 bit Windows have a memory limit of 2 GiB. This can be extended to 3 GiB with a hardware boot switch.
32 bit executables running on a 64 bit Windows have the same memory limit of 2 GiB. Using the "large address aware" flag they can at max address 4 GiB of memory.
32 bit Windows executables emulated via WINE under Linux or Unix should not be able to overcome this either, because 32 bit can at max store the number 4,294,967,295 = 2³² - 1, so the logical limit is 4 GiB in any possible way.
Wanting 17 million datasets on currently 1,9 GiB of memory means that 1,9 * 1024 * 1024 * 1024 = 2,040,109,465 bytes divided by 17,000,000 gives a mean of just 120 bytes per dataset. I can hardly imagine that is enough. And it would even only be the gross load, but memory for variables are still needed. Even if you manage to put that into large arrays you'd still need plenty of overhead memory for variables.
Your software design is wrong. As James Z and Ken White already pointed out: there can't be a scenario where you need all those dataset at once, much less the user to view them all at once. I feel sorry for the poor souls that yet had to use that software - who knows what else is misconcepted there. The memory consumption should remain at sane levels.
I installed SSMS on my windows 10 laptop for school and while on break my mates thought it would be fun to try and crash it, they did this by executing a cartesian product of the database;
select * from CAMPAIGN, COUNTRY, INVENTORY_LEVELS, ORDER_DETAILS,
ORDER_HEADER, ORDER_METHOD, PRODUCT, PRODUCT_FORECAST, PRODUCT_LINE,
PRODUCT_TYPE, PROMOTION, RETAILER, RETAILER_SITE, RETAILER_TYPE,
RETURN_REASON, RETURNED_ITEM, SALES_BRANCH, SALES_STAFF, SALES_TARGET
As i thought it would be fun to see how long it would take my pc to come up with an answer i left it running.
33 million rows (and about 20 minutes) later it stopped with the message "insufficient disk space available" and after forcing SSMS to close I checked my files only to see that my C:\ disk had 0 bytes left, after opening SSMS again it asked if i wanted to open the last recovered version or if i wanted to delete it, naturally i clicked delete but it only gave me back 4 GB on my c:\, which previously had around 32GB free.
so my question; where is the output saved on my pc? i've been looking for over an hour and i can't seem to find it
https://dba.stackexchange.com/questions/21895/system-disk-run-out-of-space-when-running-heavy-sql-queries-on-sql-server-2012
found it a couple of secconds after posting this, so quick answer:
C:\Users\Vecro\AppData\Local\Temp
it turned out to be a 31.7 million kb file see picture
i guess i learned my lesson to always, ALWAYS lock your PC when you leave it with your friends
I have the following script:
SELECT
DEPT.F03 AS F03, DEPT.F238 AS F238, SDP.F04 AS F04, SDP.F1022 AS F1022,
CAT.F17 AS F17, CAT.F1023 AS F1023, CAT.F1946 AS F1946
FROM
DEPT_TAB DEPT
LEFT OUTER JOIN
SDP_TAB SDP ON SDP.F03 = DEPT.F03,
CAT_TAB CAT
ORDER BY
DEPT.F03
The tables are huge, when I execute the script in SQL Server directly it takes around 4 min to execute, but when I run it in the third party program (SMS LOC based on Delphi) it gives me the error
<msg> out of memory</msg> <sql> the code </sql>
Is there anyway I can lighten the script to be executed? or did anyone had the same problem and solved it somehow?
I remember having had to resort to the ROBUST PLAN query hint once on a query where the query-optimizer kind of lost track and tried to work it out in a way that the hardware couldn't handle.
=> http://technet.microsoft.com/en-us/library/ms181714.aspx
But I'm not sure I understand why it would work for one 'technology' and not another.
Then again, the error message might not be from SQL but rather from the 3rd-party program that gathers the output and does so in a 'less than ideal' way.
Consider adding paging to the user edit screen and the underlying data call. The point being you dont need to see all the rows at one time, but they are available to the user upon request.
This will alleviate much of your performance problem.
I had a project where I had to add over 7 million individual lines of T-SQL code via batch (couldn't figure out how to programatically leverage the new SEQUENCE command). The problem was that there was limited amount of memory available on my VM (I was allocated the max amount of memory for this VM). Because of the large amount lines of T-SQL code I had to first test how many lines it could take before the server crashed. For whatever reason, SQL (2012) doesn't release the memory it uses for large batch jobs such as mine (we're talking around 12 GB of memory) so I had to reboot the server every million or so lines. This is what you may have to do if resources are limited for your project.
I am using Cassandra 0.8 with 2 secondary indexes for columns like "DeviceID" and "DayOfYear". I have these two indexes in order to retrieve data for a device within a range of dates. Whenever I get a date filter, I convert this into DayOfYear and search using indexed slices using .net Thrift API. Currently I cannot upgrade the DB as well.
My problem is I usually do not have any issues retrieving rows using the get_indexed_slices query for the current date (using current day of year). But whenever I query for yesterday's day of year (which is one of the indexed column), I get a time out for the first time I make the query. And most of the times, it returns when I query the second time and 100% during the third time.
Both these columns are created as double data type in the column family and I generally get 1 record per minute. I have 3 nodes in the cluster and the nodetool reports suggest that the nodes are up and running, though the load distribution report from nodetool looks like this.
Starting NodeTool
Address DC Rack Status State Load Owns
xxx.xx.xxx.xx datacenter1 rack1 Up Normal 7.59 GB 51.39%
xxx.xx.xxx.xx datacenter1 rack1 Up Normal 394.24 MB 3.81%
xxx.xx.xxx.xx datacenter1 rack1 Up Normal 4.42 GB 44.80%
and my configuration in YAML is as below.
hinted_handoff_enabled: true
max_hint_window_in_ms: 3600000 # one hour
hinted_handoff_throttle_delay_in_ms: 50
partitioner: org.apache.cassandra.dht.RandomPartitioner
commitlog_sync: periodic
commitlog_sync_period_in_ms: 120000
flush_largest_memtables_at: 0.75
reduce_cache_sizes_at: 0.85
reduce_cache_capacity_to: 0.6
concurrent_reads: 32
concurrent_writes: 24
sliced_buffer_size_in_kb: 64
rpc_keepalive: true
rpc_server_type: sync
thrift_framed_transport_size_in_mb: 15
thrift_max_message_length_in_mb: 16
incremental_backups: true
snapshot_before_compaction: false
column_index_size_in_kb: 64
in_memory_compaction_limit_in_mb: 64
multithreaded_compaction: false
compaction_throughput_mb_per_sec: 16
compaction_preheat_key_cache: true
rpc_timeout_in_ms: 50000
index_interval: 128
Is there something I may be missing? Are there any problems in the config?
Duplicate your data in another column family where the key is your search data. Row slice are mutch faster
Personally I never got to use secondary index in production environments. Or I had problems with timeout, or the speed of data retrieve by secondary index was lower that the amount of data inserted. I think that it is related with not sequentially reading data and HD seek time.
If you come from a relational model, playOrm is just as fast and you can be relational on a noSQL store BUT you just need to partition your extremely large tables. IF you do that, you can then use "scalable JQL" to do your stuff
#NoSqlQuery(name="findJoinOnNullPartition", query="PARTITIONS t(:partId) select t FROM TABLE as t INNER JOIN t.security as s where s.securityType = :type and t.numShares = :shares")
IT also has the #ManyToOne, #OneToMany, etc. etc. annotations for a basic ORM though some things work differently in noSQL but a lot is the similar.
I finally solved my problem in a different way. In fact I realized the problem is with my data model.
The problem comes because we we come from a RDBMS background. I restructured the data model a little and now, I get responses faster.
I wrote an application that performs around 40 queries and then does some processing on the results of each query. (Right now I'm using Qt 3.2.2 in Visual C++ 6.0 on Windows XP with SQL Server 2005, but that's not required.) The paradigm is to create a QSqlQuery object with the query (this causes the query to be performed) and then while (query.next()) { operate(query.value(0)); } By profiling I find that the query.next() call is taking up half the time of the program, which seems excessive as it's just fetching a row of data (6 or 7 fields).
This performance is unacceptable, and I'm looking for a way to improve this. I'm open to changing anything -- switching my compiler, switching languages, switching the paradigm I use to get data from the database. How can I speed this up?
Here's the query:
select rtrim(Portfolio.securityid), rtrim(type), rtrim(coordinate), rtrim(value)
from MarketData
inner join portfolio
on cast(MarketData.securityid as varchar(36))=portfolio.securityid
where Portfolioname=?
and type in
('bond_profit', 'bondoption_profit', 'equity_profit', 'equityoption_profit')
and marketdate=?
order by Portfolio.securityid, type, coordinate
CPU usage is around 40% while the program is running, so I suspect it's spending the majority of its time waiting for the .next() call to return with more data.
Performing the same query in SSMS returns 4.5 million rows in about 5 minutes, but the total time spent waiting on .next() during the run of the program is 30 minutes.