2013-04-03 401 views
2

我正在SSRS 2012中運行一個非常基本的報告。我只是從表中檢索一些數據,並且在查詢的Where子句中使用了一個參數。如果我在SSRS查詢中對參數進行硬編碼,查詢運行速度很快(不到5秒),但如果將其保留爲動態選擇的參數,查詢將花費5分鐘以上進行呈現。下面是類似我在用抽象查詢:SSRS報告運行速度非常慢,而查詢在SSMS中運行速度非常快

Select Col1, Count(*) 
From Tbl1 
Where Col2 = @Para1 
Group By Col1 
OPTION (RECOMPILE); 

使用的查詢選項(重新編譯)來解決參數嗅探問題,我已經嘗試過。我還檢查了數據類型,Col2是CHAR(2),Para1是TEXT,所以在運行時不需要轉換。

有什麼想法可能導致這種情況?

+0

嘗試用參數,沒有它運行在SQL管理工作室查詢(硬編碼)。看看執行計劃是否不同。 – Neolisk

+0

您可以使用COUNT(1),它可以避免處理COUNT(*)中的所有列。相同的輸出。 – criticalfix

+0

嘗試使用'存儲過程'而不是'ad-hoc'查詢 – praveen

回答

0

三件事:

  1. 爲什麼你必須使用一個重新編譯?除非你的計劃你特別想重新考慮它的執行,每次你不需要這個。特別是如果你說你的查詢很簡單。 SSRS對SQL的解釋超出了SQL的範圍,因此添加更多的東西讓它只是在尋求麻煩。如果你必須重新編譯,你可能希望把它放在一個proc中,所有的邏輯都被封裝起來以供SQL引擎理解。

  2. 參數有時會減慢SSMS中的參數查詢速度慢嗎?你提到它是快速硬編碼的,但沒有在SSMS中用參數進行測試。有時我看到SSMS的參數很慢。

  3. 你可以用小技巧'欺騙'SSRS的參數部分。在參數特別糟糕的極端情況下,您可以構建一個在運行時運行的表達式。在您的數據集選項點擊「FX」的表達,然後做到這一點:

    ="Select Col1, Count(*) 
    From Tbl1 
    Where Col2 = " & Parameters!Para1.Value 
    

只要你的類型是文本,這應該產生一個合法的字符串,然後在運行時進行評估。有一點需要注意的是你的字段可能不會自填充,所以你可能希望做實際的查詢,讓它們自動填充,然後返回並放入函數。否則,你將不得不手動設置字段左邊的窗格數據集說明'領域'這是一個痛苦恕我直言。

2

我有類似的問題,但只有當連接到Oracle數據庫。當我在查詢中對參數進行硬編碼時.... ....效果很好.....將參數傳遞給查詢,並且它將持續使用。奇怪的是,它只會持續一些參數。在我的情況下,當我檢查日誌時,渲染時間一直在持續。 (還應該提到這是一個多選PARAM ......沒有辦法圍繞獲得的)

奇怪的解決方案:

而不是傳遞參數到查詢,我通過它變成數據集作爲過濾。有人會認爲這隻會增加ssrs服務器上的負載,因爲你需要通過網線發送更多的數據來處理......因此增加了渲染時間,但不同之處在於夜晚和日間。報告現在運行良好。

老實說不能解釋。

我寫了更多的報告,比我可以對SQL Server數據源進行計數,並且在連接到Oracle時只看到了這個(以及其他一些奇怪的東西)。但如果您遇到同樣的問題,可能值得一試,而且您所應用的參數實際上並不會限制數據。 (大多數人在我的情況下都是在運行'all'

如果你不熟悉在數據集上使用過濾器,請轉到此鏈接並查找標題「Using Filters with Multiple Value Parameters」(適用於非多值PARAMS以及)http://www.mssqltips.com/sqlservertip/2866/sql-server-reporting-services-using-multivalue-parameters/

0

我經歷了同樣的問題。我跑了SQL Server Profiler中 Sniffing queries to SQL Server 以確定該報告是緩慢的,發現運行20秒的查詢,查詢被包裹在exec sp_executesql。我將查詢複製到SSMS,並發現它運行20秒。將查詢轉換爲直接SQL使其運行1秒AhHah!

返回到EXEC sp_executesql的 SQL,有一個在第如預期:

operid IN (N''XICL002'',N''XICL005'',N''XICL026'',N''XICL028'... 

operid被decared VARCHAR(32),而Ñ前綴強制參數NVARCHAR。刪除N使exec sp_executesql sql在1秒內運行。

在我的情況下,我能夠修改報告。 IN子句由多選參數(p_operators)填充。我改變了報表查詢以使用生成p_operators列表的參數從視圖中獲取operid列表。

operid IN (SELECT oper_id FROM foo WHERE (foo1 IN (@p_foo1)) AND (foo2 IN (@p_foo2)) AND ... 

基本上,將參數從NVARCHAR轉換爲VARCHAR會導致性能下降。似乎SSRS應該提供指示參數數據類型的選項 - 而不僅僅是「文本」。另外,在開發模式下的一些日誌記錄也會很好。

(我希望我提供足夠的信息是有用的。由於業公司的政策,我不能寫太多)

1

我在使用查詢來加載數據的報告也有類似的問題。就我而言,我必須支持由架構團隊建立的開發模式(在SSRS數據集中使用直接查詢)。我無法使用過濾器,因爲未經過濾的數據量和安全要求(僅從數據庫提取請求的數據)。

所以我的解決方案是攻擊轉換。我聲明瞭表變量,用來自SSRS參數的轉換選擇值填充這些變量,並在WHERE … IN (…)表達式中使用這些表變量。這涵蓋了所有要求僅查詢,有限數據量,安全數據訪問並解決了NVARCHAR到VARCHAR轉換速度減慢。

查詢解決方案看起來像這樣(@pSelectedValues是可變映射到報表選擇參數,它在我修改前已經存在):

DECLARE @tMySelectedParameterValues TABLE(SelectedValue varchar(255) NULL); 

INSERT INTO @tMySelectedParameterValues 

SELECT DISTINCT EntityStatusStatusName 
FROM  dbo.t_MyReferenceData 
WHERE  ValueForParameters IN (@pSelectedValues); 

... main selection and from parts .... 

WHERE keyValues IN (SELECT SelectedValue FROM @tMySelectedParameterValues) 
相關問題