2009-11-19 33 views
0

我正在嘗試對Microsoft SQL Server進行相當多的查詢,我只能讀取它。我的查詢需要使用與數據庫體系結構完全不同的結構來處理數據。由於我只有閱讀權限,因此我無法創建視圖,因此我正在尋找解決方案。 我目前正在做的是使用複雜的查詢來返回結果,因爲我需要它們,但是這是4-5表連接子查詢。它速度慢,資源密集。 我可以看到兩個解決方案,但會喜歡聽到什麼,我可能會錯過:使用只讀訪問模擬SQL Server視圖的方法?

  • 使用某種形式是緩存數據,以及圍繞它產生的意見「代理」的。這需要某種方法來確定數據的不清楚。 (是否有這樣的東西?)
  • 運行我自己的SQL服務器,並每隔X分鐘從源SQL服務器鏡像數據,然後在我的SQL服務器上加載視圖。

還有其他想法嗎?或對這些想法的建議?

謝謝!

+0

您是否有權創建存儲過程? – 2009-11-19 21:56:50

+1

爲什麼你認爲視圖會更快? – HLGEM 2009-11-19 22:08:29

+0

不,我可以*只讀*數據。 視圖被緩存。 – Loki 2009-11-19 22:10:55

回答

0

如果您可以在該服務器上創建新數據庫,則可以在新數據庫中創建視圖。視圖可以使用三部分名稱訪問數據。例如。從OtherDB.dbo.Table中選擇*。

如果您有權訪問另一個SQL服務器,DBA可以創建一個「鏈接服務器」。然後,您可以創建使用四部分名稱訪問數據的視圖。例如。 select * from OtherServer.OtherDB.dbo.Table

無論哪種情況,數據總是「活」的,所以不需要擔心臟數據。

這些視圖將爲您帶來更簡潔的代碼和單個位置以進行更改,並且緩存的執行計劃可爲您帶來幾毫秒的性能優勢。但是,不應該有很大的表現飛躍。您提到緩存,但據我所知,服務器不會爲特殊查詢所不會執行的任何特殊的數據緩存用於普通的非索引視圖。

如果您還沒有這樣做,您可能希望做一些實驗來確定視圖是否真的更快 - 製作數據庫的副本並在其中添加視圖。

編輯:我今天做了一個類似的實驗。我在Server1上存儲了一個通過鏈接服務器從Server2獲取數據的proc。這是一個複雜的查詢,連接了兩臺服務器上的許多表。我在Server2上創建了一個視圖,該視圖從服務器獲取所需的所有數據,並更新了proc(在Server1上),以便它使用該視圖(通過鏈接服務器),然後將視圖加入到一堆表中在Server1上。更新後顯着更快。原因似乎是Server1錯過了從Server2獲得的行數,從而構建了一個糟糕的計劃。在使用視圖時,它估計得更好。如果視圖與其讀取的數據位於同一個數據庫中並不重要,它只需要放在同一個服務器上(我只有實例,所以我不知道實例是如何起作用的) 。

如果您已經在使用鏈接服務器來獲取數據,這種特殊場景纔會起作用,因此它可能與原始問題無關,但我認爲這很有趣,因爲我們正在討論視圖的性能。

2

這裏有一些方法供您選擇:

複製

設置複製到數據移動到自己的SQL Server和創建你所需要那邊的任何意見。管理員必須設置它。如果您需要在數據更改時查看數據,請使用事務複製。如果沒有,你可以做快照。

在這裏閱讀更多:http://technet.microsoft.com/en-us/library/ms151198.aspx

新DB在同一個實例

獲取一個新的數據庫MYDB在同一臺服務器上ProductionDB與你寫訪問。在那裏創建你的觀點。

您的視圖創建可以是這樣的:

USE MyDB 
GO 
CREATE VIEW DBO.MyView 
AS 

SELECT Column1, Column2, Column3, Column4 
FROM ProductionDB.dbo.TableName1 t1 
    INNER JOIN ProductionDB.dbo.TableName2 t2 
     ON t1.ColX = T2.ColX 

GO 

相同的實例,而不是相同的服務器+差異實例:我建議對SQL Server作爲ProductionDB的同一個實例創建MYDB,而不是安裝一個新的實例。單個機器上的多個SQL Server實例在資源方面比同一實例上的新DB要昂貴得多。

標準可重複使用的次數

建立一套規範的意見和要求管理者把他們給你的只讀服務器和重用查詢這些觀點

+0

你的第二個答案可能是一個可能的解決方案 - 你可以有一個視圖,從相同服務器上不同數據庫中的表獲取數據?我從來沒有嘗試過... – Loki 2009-11-19 22:15:06

+0

@Lokkju:研究SQL Server的鏈接服務器。最好的選擇是如果你能夠處理數據的鏡像,那麼你可以創建視圖而不用擔心會損害數據。 – 2009-11-19 22:18:39

+0

@Lokku:你可以使用3部分的名字來完成。 dbname.dbo.table 其中dbo是所有者(我認爲) – 2009-11-19 22:29:48

0

你可以要求DBA來創建架構像你這樣的人「承包商」,並允許你只在該模式內創建對象。

+0

此SQL服務器是具有SQL服務器和某些程序的「產品」的一部分。爲了保持suuport,我們只能查詢SQL服務器。由於它是一個打包產品,因此要讓作者實現我們需要報告的東西是相當困難的。 – Loki 2009-11-19 22:12:35

1

你也可以使用CTE,它可以像一個視圖。

如果Raj More的#2建議不適合你,我會去做的...

WITH myusers (userid, username, password) 
AS 
(
    -- this is where the definition of view would go. 
select userid, username, password from Users 

) 


select * from myusers 
+0

CTE執行與內聯視圖相同的操作 - 在SQL Server和Oracle中,沒有差別的性能/等等。 – 2009-11-19 22:30:06

+0

它只是使查詢更具可讀性...... – 2009-11-19 22:44:29

0

我會看管理工作室中的查詢計劃,看看您是否可以說明爲什麼它表現不佳。也許你需要重寫你的查詢。如果有幫助,您也可以使用表級變量作爲臨時表來存儲中間結果。只要確保你沒有在其中存儲大量記錄。您可以像這樣在批處理中運行多個語句:

DECLARE @tempTable TABLE 
(
    col1 int, 
    col2 varchar(250) 
) 

INSERT INTO @tempTable (col1, col2) 
SELECT a, b 
FROM SomeTable 
WHERE a < 100 ... /* some complex query */ 

SELECT * 
FROM OtherTable o 
INNER JOIN @tempTable T 
ON o.col1 = T.col1 
WHERE ... 
0

通過使用視圖,您的查詢不會表現更好。您需要調整這些查詢,並且可能需要在這些表上創建一些索引以支持您的查詢。

如果您無法訪問數據庫,爲了創建這些索引,您可以將數據「緩存」到您創建的新數據庫中,然後在新數據庫中調整您的查詢。當然,您將不得不實施一些同步,以使緩存的數據保持最新狀態。

通過這種方式,您將不會立即看到對原始數據庫所做的更改(將有延遲),但可以使查詢執行得更快,甚至可以根據需要創建這些視圖。

+0

我剛剛意識到,這不是模擬視圖的答案,而是解決這些查詢所具有的性能問題。 – treaschf 2009-11-24 14:20:07