2013-04-12 74 views
1

我們有一個支持大約500多個用戶的Windows應用程序(用.Net編寫)。這個應用程序有一個特定的功能,它將帶回每天運行少量時間的大約40k條記錄(在MS SQL Server上)。影響整個系統的大型數據庫查詢

但是,當運行這個大型查詢時,系統的其他用戶似乎是「定時」,這對我來說似乎意味着大型查詢佔用服務器資源並導致其他用戶無法使用系統正常。

我想了解資源分配是如何工作的,因爲我覺得像一個40k查詢並不完全是巨大的,但體積相當大。

我們的應用程序體系結構的用戶界面 - >服務層 - > Web服務 - >數據庫

難道是導致問題或可能我的查詢可能會被「鎖定」的SQL數據庫,而不是讓Web服務其他用戶與它交互?

SQL查詢非常簡單,它直接從特定表中選擇所有記錄(此表包含從其他表中提取的數據,現在大約有40k條記錄,表中有大約50列):

SELECT * 
FROM MyTable 

幾乎是查詢。沒有連接,我正在使用存儲過程。

+4

可能是後者,你的查詢佔用數據庫服務器。你能向我們展示查詢和相關表結構嗎?或者也許是一個執行計劃?也可能是查詢返回了一個非常大的結果集,導致Web服務器在內存使用率上激增。 – alexn

+0

你查詢的是什麼樣子?它影響了多少個表格?它有很多連接嗎?你可以使用視圖而不是直接使用表格嗎?你可以使用存儲過程嗎?你能緩存結果嗎? –

+0

執行此查詢並返回SSMS中的所有記錄需要多長時間? –

回答

1

我真的沒有足夠的信息說任何明確的,但我可以做一些猜測/建議。

首先,如果沒有寫入此表的任何來源......當查詢處於活動狀態時,您可以通過向該選擇添加with (nolock)提示來改善內容。再次說明:只有在查詢過程中表格保持不變的情況下才執行此操作,或者如果您對此查詢感到滿意,則生成的結果由於髒讀而失效/錯誤。

此外,在您對該查詢的描述中,「非常多」這個短語表示可能有其他的東西我們沒有看到;它仍然很簡單,但它是一些東西。如果這是ORDER BY子句,那麼使命令與主鍵匹配(或將主鍵與您需要的順序對齊)也可能會有所幫助。

至於web服務層vs數據庫作爲瓶頸,這應該很容易確定。如果是網絡服務,您會知道,因爲服務器上的CPU,RAM或網絡I/O會在服務層達到100%,從而淹沒其他客戶端。可能它是服務,因爲服務網絡層必須處理所有數據兩次:一次是從數據庫中拉下來,一次是將數據重新傳輸給最終用戶客戶端。所以它對數據使用有一個小的乘數效應。但即使有這種效果,我認爲數據庫更可能是罪魁禍首。

最後的建議是,如果這些數據過時可以,您可以嘗試將代碼添加到服務層以緩存它。

+0

謝謝喬爾,我很抱歉,因爲我認爲我誤解了。有寫入表格,只是不在查詢中拉取數據。我對這種混亂表示歉意。如果使用(nolock),如果在查詢過程中嘗試寫入,會導致異常嗎? – mint

+0

不,但它可能會導致您返回意外的數據。 –

1

如果您從MyTable中選擇*,它將鎖定表,以便其他人都必須等待。

首先要檢查你的代碼,你如何閱讀記錄?如果您使用的是數據讀取器,它將鎖定表格直到關閉它。使用SQLDataAdapter並將其放入表中。這隻會將表格鎖定在實際需要的時間內。

另一件事是死難者會說不要做一個*拉。只拉你需要的領域。

如果你不介意有'骯髒'的數據(未提交)做一個選擇*從mytable(nolock)。這意味着它將獲得尚未提交的任何內容。但是如果表格不變,那應該是一個問題。

0

40k行x 50列是在具有500多個用戶的實時系統上提取大量數據。假設這50列的平均列大小爲20個字節,那麼您將檢索大約800k的數據,但是如果您有很多varchar的100個字節長,那麼這個大小會大幅增加。

我會質疑爲什麼你需要這樣一個巨大的查詢,它顯然是太多的數據讓人們在屏幕上舒適地查看。如果數據提取是爲了給其他數據存儲提供數據,那麼只考慮使用不在辦公室的時間,或者讓一個進程在後臺批量提取數據或將數據複製到單獨的服務器。

+0

在內部局域網上的800K是沒有的。 –

+0

是的,它是用於數據提取,而不是用戶正在拉起來查看作爲「活的查詢」。 – mint

+0

@Joel Coelhoorn當數據通過已經處理大量處理和I/O請求的服務器將數據傳送到LAN上時,它本身對局域網本身並不是問題,但它可能是重要的。 800k也可能是一個連續的數字。 –