I am using a stored procedure as a dataset in an SSRS report. Even though the stored procedure is running fast enough, the report is taking too long to process.
For the same set of parameters the stored procedure is giving result in 4-7 seconds but the SSRS report is taking around 4 minutes to pop up.
The data from coming from the stored procedure is big but not too big... its around 13k. Also I cant Implement grouping in Stored Procedure so I am grouping in the report itself. However, even after removing the grouping the performance got better merely (like 40 seconds less time).
Trying to figure out the issue and willing to discuss it as I am having similar issue with 2-3 reports.
Please, any help will be appreciated.
Thank You in advance.
The way a stored procedure is written can affect the performance. from your description if you implement the second procedure below. i believe it will improve the performance.
SLOW Stored Procedure
CREATE PROC SLOW_PROC (#ID INT)
AS
BEGIN
SELECT
ID
,Name
FROM MyTable
WHERE ID =#ID
END
Fast stored procedure
CREATE PROC FAST_PROC (#ID INT)
AS
BEGIN
DECLARE #NewID INT SET #NewID=#ID
SELECT
ID
,Name
FROM MyTable
WHERE ID =#NewID
END
The difference may not be much but the performance is.
I hope this help
Related
My desired end result is to simply be able to SELECT from a Stored Procedure. I've searched the Internet and unfortunately the Internet said this can't be done and that you first need to create a Temp Table to store the data. My problem is that you must first define the columns in the Temp Table before Executing the STORED Procedure. This is just time consuming. I simply want to take the data from the stored procedure and just stick it into a Temp Table.
What is the FASTEST route to achieve this from a coding perspective? To put it simply it's time consuming to first have to lookup the returned fields from a Stored Procedure and then write them all out.
Is there some sort of tool that can just build the CREATE Table Statement based on the Stored Procedure? See screenshot for clarification.
Most of the Stored Procedures I'm dealing with have 50+ fields. I don't look forward to defining each of these fields manually.
Here is good SO Post that got me this far but not what I was hoping. This still takes too much time. What are experienced SQL Server guys doing? I've only just recently made the jump from Oracle to SQL Server and I see that Temp Tables are a big deal in SQL Server from what I can tell.
You have several options to ease your task. However, these won't be fully automatic. Be aware that these won't work if there's dynamic sql in the procedure's code. You might be able to format the result from the functions to increase the automation allowing you to copy and paste easily.
SELECT * FROM sys.dm_exec_describe_first_result_set_for_object(OBJECT_ID('report.MyStoredProcedureWithAnyColumns'), 0) ;
SELECT * FROM sys.dm_exec_describe_first_result_set(N'EXEC report.MyStoredProcedureWithAnyColumns', null, 0) ;
EXEC sp_describe_first_result_set #tsql = N'EXEC report.MyStoredProcedureWithAnyColumns';
GO
If you don't mind ##temp table and some dynamic SQL
NOTE: As Luis Cazares correctly pointed out... the ##temp runs the risk of collision due to concurrency concerns
Example
Declare #SQL varchar(max) = 'Exec [dbo].[prc-App-Lottery-Search] ''8117'''
Declare #temp varchar(500) = '##myTempTable'
Set #SQL = '
If Object_ID(''tempdb..'+#temp+''') Is Not NULL Drop Table '+#temp+';
Create Table '+#temp+' ('+stuff((Select concat(',',quotename(Name),' ',system_type_name)
From sys.dm_exec_describe_first_result_set(#SQL,null,null ) A
Order By column_ordinal
For XML Path ('')),1,1,'') +')
Insert '+#temp+' '+#SQL+'
'
Exec(#SQL)
Select * from ##myTempTable
I have a SSRS Report which is using a dynamic SQL Server stored procedure with one parameter only and it works fine.
I want to create a report which whenever I run it, it loop through multiple values for that parameter and creates multiple results, instead of doing that manually.
I found below links from Stack Overflow, but none of them help a lot.
Link1
Link2
I also read some I can use List in SSRS, but I am not sure how to do it in my case.
Any idea?
This might not be an answer as you have not provided enough detail, but I'm sure this idea will help you.
I think you'd better to change your stored procedure to accept multiple values and in your procedure return multiple result sets or combine record sets for each parameter value.
For example, assume you have procedure Proc1, which gets a number as parameter.
create procedure Proc1 (#aYear int)
as
begin
select *
from Orders
where OrderYear = #aYear
end
Now, what you need to do is changing your procedure to accept multiple years (for instance as a comma separated value)
create procedure Proc1 (#csv_years varchar(100))
as
begin
-- use some function or techniques to split the #csv_years
-- and store it into a temp table #years ([Year] int)
-- now, join your main data with this #years table
select #years.[Year], Orders.*
from Orders
inner join #years on #years.Year = Orders.OrderYear
end
Now, your are returning the result for multiple years and you can show that in your report by grouping on [Year] column
You need to use data driven subscription. I had cases with dynamic parameters and the only solution was data driven subscription.
SP is RecordSource of the form.
When form is opened SP executed and after a time-out of query, connection is closing with nothing.
If SP executed from SSMS it performed for about 2 seconds and returns a set of records.
As I watched through the SSMS Profiler calls are identical, but count of Reads value (an execute from Access) > 28 million, and about 70 thousand from the SSMS.
Help me, I'm confused.
Screen with profiler
http://take.ms/u7tTy
#tobypls,
thank you very much - your link was helpful.
Simple solution is rewrite (for example)
from
ALTER PROCEDURE [dbo].[sproc]
#param1 int,
AS
SELECT * FROM Table WHERE ID = #param1
to
ALTER PROCEDURE [dbo].[sproc]
#param1 int,
AS
DECLARE #param1a int
SET #param1a = #param1
SELECT * FROM Table WHERE ID = #param1a
I get it from this post.
But if you need full understanding of trouble then you must read really great article
Slow in the Application, Fast in SSMS?
Understanding Performance Mysteries
I have below SP:
CREATE PROCEDURE [dbo].[ups_Ins_TblA] #ID int, #Comment nvarchar(max) AS
BEGIN
SET NOCOUNT ON
INSERT INTO [db_assets].[Claim]
(ID,Comment)
Values
(#ID,#Comment)
END
Basically, my question is, is there a way to call this in BCS Sharepoint(Business Connectivity Service) using out-of-the-box functionality? Can I further adjust the SP so that it can be supported with all 'CRUD' operations? Pls suggest ideas?
Note: I have made the table as simple as possible.
I don't want to make a straight-insert from the table because I have to join this to another table where document resides that's why I want to use SP.
I'd been spending almost 2-3days reading and still going on.. If anyone can direct me to the light, pls help? Thank you so much!!
This is a noob mistake. Apologies.
The answer is to write your stored procedure separately and assign it the each operation accordingly (Read Item, read List, Create, Update, Delete).
Yes, there will be 5 sp.
As long as the mapping of identifier is set appropriately, the creation of Lists will not have issue (with CRUD operation enabled).
I have a Stored Procedure that rolls-back a series of operations. I want to call this from within another SP.
The problem is that the inner SP returns a record set with a single value that indicates the degree of success.
This approach worked well and has some advantages in our context, but in retrospect, I would have done it the conventional way with a Return value or an Output parameter.
I could always change this SP to use this approach and modify the calling code, but a) I don't want to dabble with any more code than I have to, and b) at an intellectual level, I'm curious to see what alternative solution there may be, if any.
How (if at all) can I call this SP and determine the value of the singleton recordset returned?
Thanks
A stored procedure returns a record set like any other, so you can actually do this:
INSERT INTO MyTable (
MyValue
)
EXEC dbo.MyStoredProcedure
The EXEC takes the place of a SELECT statement. To get the value, just SELECT from the table you inserted into. Typically, this would be a temp table.
The other option is to convert the stored procedure that returns a recordset into a function that returns a table.
Ant's approach is probably best if you want to minimize the changes to your system.
Normally you would use a temporary table for that approach since you can't use an exec statement to insert into a table variable.
Here's a variation which will work well if you need to use this for MULTIPLE recordsets.
CREATE TABLE #outsidetable (...)
exec spInsideProcedure
SELECT * FROM #outsidetable
inside spInsideProcedure
INSERT INTO #outsidetable SELECT <blah blah blah>
I tried Ant's approach and it worked a treat:
Declare #Success tinyint
Declare #Response Table (Success int)
Insert into #Response(Success)
Exec Fix_RollbackReturn 12345, 15
Select #Success=Success from #Response
As you can see I used a Table Variable rather than a temporary table because slightly more efficient than a temporary table.
Thanks for all your help guys.
EDIT: It appears that Dave was right after all. That is, my Exec-into-Table-variable approach worked on my SQL2005 development machine, but when moved to the Live (SQL2000) machine it objected, so I had to change to the temporary table approach.
It's a little annoying, especially since in a couple of weeks we are upgrading to SQL2005 across the board(!).