Reporting Services can be demanding in terms of memory and CPU, so it often makes sense to separate it from the database server element of SQL Server - obviously this isn't cheap in terms of licencing. One thing to bear in mind is that the metadata for SSRS is stored in a SQL database, but this can be on a different box. Where SSRS gets the business data from depends on where that data resides - it could be anywhere, but it might be a SQL database somewhere.
If your SSRS deployment uses subscriptions to generate reports out-of-hours, and your SQL database is used for other requirements during business hours, then it might make sense to keep them on one box.
Depending on your SQL edition, and your requirements, you can also treat the separate SSRS boxes like webservers, and have them in a high availability Network Load Balanced cluster - you can't cluster SSRS in the same way that you can with the database engine for high availability.
Like anything, try to test it all in a pre-production or Proof Of Concept environment.
It appears as though even with a ... WHERE 0 = 1
clause that there will still be a requirement for an intent shared (IS
) lock on the table. Let's prove this:
I will start out by creating a test table:
use TestDb1;
go
create table dbo.MyTestTable1
(
Id int identity(1, 1) not null,
SomeInt int not null
);
go
insert into dbo.MyTestTable1 (SomeInt)
values (10), (20), (30), (40), (50);
go
Now that I have my test table, in one session (query window) I'm going to execute the following to put an exclusive (X
) lock on dbo.MyTestTable1
:
use TestDb1;
go
begin tran;
select
Id, SomeInt
from dbo.MyTestTable1 with (tablockx);
--commit tran;
I can verify the exclusive lock by looking at the sys.dm_tran_locks
DMV. Then in another session (new query window) I do exactly what your query does:
use TestDb1;
go
select
Id, SomeInt
from dbo.MyTestTable1
where 0 = 1;
At first glance I see that it isn't completing. Looking at sys.dm_exec_requests
, I see exactly why this is the case:
select
r.session_id,
r.status,
r.wait_type,
r.wait_time,
r.wait_resource,
r.blocking_session_id
from sys.dm_exec_requests r
cross apply sys.dm_exec_sql_text(r.sql_handle) st
where st.text like '%where 0 = 1%'
and r.session_id <> @@spid;
I can see here that my ... WHERE 0 = 1
query is waiting on an IS
lock for this object (that object_id translates to dbo.MyTestTable1
).
I am by no means saying that concurrency is your problem, but by the sounds of it you are exhibiting the symptoms. The example above is to prove that your aren't exempt from locking and blocking even with a WHERE
clause that'll never return data.
All we can do is guess, so what you need to do when it's "taking a long time" is to see exactly what that request is doing that is taking so long. If it's waiting on something, then see what it's waiting on.
Best Answer
I see that it's an old thread but you can essentially have different Shared Schedules to expire and refresh the cache executed in that order to solve the problem.