2014-12-31 56 views
0

在一行rdr.GetString需要12-15秒慢速SqlDataReader的GetString的

幾個行需要4 - 5秒
幾採取1-4秒
大多數行是小於100毫秒

整個查詢只返回SSMS 3,286行,運行在15秒

[超值]爲varchar(600) - 沒有什麼特別的地方,我知道
有上[fieldID],[值的索引]重建(s everal次)

在SqlDataReader的讀出行208需要12 - 15秒
讀取一行,只要需要爲閱讀所有剩餘的3285行

的如果我更改排序上[fieldID]來說明那掛在行2050
而這是不一樣的行(它甚至不是同一[fieldID])

的rdr.GetString是rdr.GetByte它從不掛在了getByte之前。 它已經有排! 即使打到另一臺具有類似但不精確的數據庫的服務器,它也會掛起。

我知道這聽起來很瘋狂,但它正在發生。 這感覺就像SqlDataReader掛起,但我在這個應用程序中一直使用SqlDataReader並返回比這更多的行。

如果我在fieldID更改時手動執行GC.Collect(),它仍然掛在大多數相同的行上。 個人掛起的時間有點小,但總數大致相同。使用1秒的閾值可能有一個剛剛進入或剛剛進入狀態,但問題行肯定會重複。

認爲它可能與掛鉤之間的字符數有關,但可以低至600和高達60,000。

但它似乎與返回的數據有關。 如果我排除或包含[rownumber](並且不讀取它),它將掛在不同的行上。 但行在相同的附近。

fieldID = rdr.GetByte(0); // this line does not hang 
delta = sw.ElapsedMilliseconds; 
textValue = rdr.GetString(1); // this is the line that hang on some rows 
if ((sw.ElapsedMilliseconds - delta) > 1000L) 
    Debug.WriteLine("GabeLib_Helper sw in fields thisFieldID = " + thisFieldID + " counter = " + counter + " ccount = " + ccount + " after getstring read delta = " + (sw.ElapsedMilliseconds - delta).ToString("N0") + " textValue = " + textValue); 

select [fieldID], [value], [rowNum] 
from 
(
SELECT [fieldID], ltrim(rtrim([value])) as [value] 
    , ROW_NUMBER() over (partition by [fieldID] order by ltrim(rtrim([value]))) as [rowNum] 
    FROM [docSVtext] with (nolock) 
    JOIN [docFieldDef] with (nolock) 
    ON [docFieldDef].[ID] = [fieldID] 
    AND [docFieldDef].[typeID] in (101) 
    AND [docFieldDef].[active] = 'true' 
    AND len(ltrim(rtrim([value]))) > 0 and len(ltrim(rtrim([value]))) <= 200 
    JOIN [docSVsys] with (nolock) 
    on [docSVsys].[sID] = [docSVtext].[sID] 
    and [docSVsys].[visibility] = 0 
group by [fieldID], ltrim(rtrim([value])) 
) as withRow 
where [rowNum] < 1001 
order by [fieldID], [rowNum] 

如果我添加rdr.GetInt64(2);上面的rdr.GetString(1);
然後掛在rdr.GetInt64(2);並不會掛在rdr.GetString(1);
並與rdr.GetInt64(2);我得到一個慢rdr.Read()。

delta = sw.ElapsedMilliseconds; 
rowNum = rdr.GetInt64(2); 
if ((sw.ElapsedMilliseconds - delta) > 1000L) 
    Debug.WriteLine("GabeLib_Helper sw in fields in PastEntries new rowNum rdr.GetInt64(2) " + rowNum + " counter = " + counter + " ccount = " + ccount + " delta = " + (sw.ElapsedMilliseconds - delta).ToString("N0")); 

在SSMS
下方運行查詢2秒這是沒問題的查詢
包括顯示索引似乎是工作

select fieldID, value, count(*) 
    from docSVtext 
    group by fieldID, value 

我跟蹤GC,這是不相關的緩慢起伏
即使GC運行時也只需要20 ms

delta = sw.ElapsedMilliseconds; 
List<int> gcCounts = new List<int>(); 
for (int g = 0; g <= GC.MaxGeneration; g++) gcCounts.Add(GC.CollectionCount(g)); 
textValue = rdr.GetString(1); // " Chen, Andy </O=ENRON/OU=NA/CN=RECIPIENTS/CN=ACHEN>" + Guid.NewGuid(); // 
if ((sw.ElapsedMilliseconds - delta) > 100L) 
{ 
    Debug.WriteLine("GabeLib_Helper sw in fields thisFieldID = " + thisFieldID + " counter = " + counter + " ccount = " + ccount + " after getstring read delta = " + (sw.ElapsedMilliseconds - delta).ToString("N0") + " textValue = " + textValue); 

} 
for (int g = 0; g <= GC.MaxGeneration; g++) 
{ 
    if (GC.CollectionCount(g) != gcCounts[g]) 
     Debug.WriteLine("GabeLib_Helper GC new count = " + GC.CollectionCount(g) + " old count =" + gcCounts[g] + " generation " + g + " ccount = " + ccount + " after getstring read delta = " + (sw.ElapsedMilliseconds - delta).ToString("N0")); 
} 
+0

@Rhumborl但它掛在GetString - 這是一個用詞不當嗎?如果我將textValue賦值爲硬編碼的「值」,它沒有問題 – Paparazzi

+0

第一個查詢是導致問題的第一個查詢嗎?即'order by fieldID,rownum'加上'desc'加入它?如果是這樣,請嘗試在子查詢的'order by'子句中刪除'ltrim(rtrim(..))'。 – shahkalpesh

+0

@shahkalpesh沒有解決問題。它現在掛在不同的行上。正如我所說的,查詢在SSMS中運行得很好。它已經在該行上執行了rdr.GetByte(0),沒有任何問題。 – Paparazzi

回答

0

我想我想通了

如果我刪除

where [rowNum] < 1001 

則沒有任何排很長的讀取
查詢需要更長的時間因爲現在它讀取每一行
那掛時它跳過過去那些行
由於實際的讀者提前讀這是很難看到

但在SSMS沒問題仍然讓我困惑

嘗試了

select ID, count(*) 
    from table 
    ... 
group by ID 
having count(*) > x 

查詢僅針對那名X計數
問題下查詢了幾秒鐘的ID運行

我最終什麼事做的是

select top (x + 1), value 
    from table 
where ID = i1 
group by value; 
select top (x + 1), value 
    from table 
where ID = i2 
group by value; 
... 

如果計數達到x + 1,則我不使用它

發生了什麼事情是一些非常大的計數,在那裏吃了很多時間,我甚至都不想要這些。即使得到一個大數的計數是昂貴的