2010-01-06 40 views
4

在我們的組織中,我們需要讓員工通過提供WHERE子句來過濾Web應用程序中的數據。它很長一段時間偉大的工作,但我們偶爾會碰上需要對大型表或低效聯接全表掃描用戶提供查詢等確保僅「合理」查詢

有些小丑會寫類似:

select * from big_table where 
Name in (select name from some_table where name like '%search everything%') 
or name in ('a', 'b', 'c') 
or price < 20 
or price > 40 
or exists (select 1 from some_other_table where col1 + col2 + col3 = 4) 
or exists (select 1 from table_a, table+b) 

顯然,這不是用計算值,非索引列,大量OR和table_a和table_b上的無限制連接查詢這些表的好方法。

但是對於用戶來說,這可能是完全有意義的。

那麼,如果允許內部用戶向數據庫提供查詢,同時確保它不會鎖定一打表並將Web服務器掛起5分鐘,最好的方法是什麼?

我猜這是在c#/ sql-server中的編程方式,以便在查詢運行之前獲取查詢的執行計劃。如果是這樣,哪些因素會造成成本?估計的I/O成本?預計的CPU成本?什麼是合理的限制,告訴用戶他的查詢不好?

編輯:我們是一家市場研究公司。我們有數千次調查,每次調查都有自己的數據。我們有數十位研究人員想要以任意方式分割這些數據。我們有工具讓他們使用GUI構建「有效」的過濾器,但一些「高級用戶」想提供自己的查詢。我意識到這不是標準或最佳實踐,但我怎麼可以讓數十個用戶使用任意複雜的條件和不斷變化的條件來查詢他們想要的行的表?

+0

除了在客戶和編寫WHERE子句之間提供某種層次的答案之外,爲常見查詢設置視圖又如何呢? – Zwergner 2010-01-06 19:34:20

+2

我會將數據複製到數據倉庫,讓用戶在那裏分析數據安全的地方。 – CaffGeek 2010-01-06 19:55:00

回答

3

您可以嘗試使用以下:

SET SHOWPLAN_ALL ON 
GO 
SET FMTONLY ON 
GO 
<<< Your SQL code here >>> 
GO 
SET FMTONLY OFF 
GO 
SET SHOWPLAN_ALL OFF 
GO 

然後你就可以通過你有什麼分析。至於在各種事物上劃定界線的方法,這將需要一些經驗。有一些需要注意的事情,但沒有切斷和乾燥的東西。與科學相比,檢查查詢計劃往往更像是一門藝術。

正如其他人指出的那樣,我認爲你的問題比技術含義更深入。事實上,你讓不合格的人以這種方式訪問​​你的數據庫是潛在的問題。從過去的經驗來看,我經常在那些懶惰或經驗不足的公司看到這一點,以便正確地捕捉應用程序的需求。我並不是說你的企業環境就是這種情況,但這就是我見過的。

0

我想你從來沒有聽說過SQL注入攻擊?如果用戶在WHERE子句之後輸入DROP DATABASE命令會怎麼樣?

+0

a)這些是我們的員工正在使用該應用程序。有些是愚蠢的,沒有一個是惡意的。 b)查詢只使用只讀用戶來運行。 – 2010-01-06 19:30:16

+0

有效的關注,但不是真正的問題答案。 – Zwergner 2010-01-06 19:30:50

+5

我會小心假設員工從不惡意...... :) – 2010-01-06 19:36:37

1

爲了不讓員工直接編寫(附加到)查詢,然後在運行查詢之前嘗試計算查詢成本,爲什麼不創建某種高級搜索或過濾功能,而不是編寫無法控制的SQL?

5

你的問題狀態的前提:

在我們的組織,我們有必要讓員工過濾日期在我們的web應用程序通過提供WHERE子句。

我覺得這個前提有缺陷。我無法想象我會允許用戶這樣做的情況。除了您已經確定的問題之外,您還將面臨SQL注入攻擊。

我強烈建議重新評估您的要求,看看您是否無法構建更安全,更集中的方式讓用戶進行搜索。但是,如果您的用戶確實是足夠複雜(且值得信賴的),直接提供WHERE子句,則需要對他們可以或不可以提交的過濾器進行教育。

+0

同意。如果確實要求的確是允許用戶直接發佈查詢(瘋狂!),那麼教育是最好的途徑。 – 2010-01-06 19:51:35

0

這是直接SELECT權限在絕大多數應用程序中幾乎從不給用戶的原因。

更好的方法是圍繞用例設計您的應用程序,以便您可以通過專門設計的過濾器/聚合/佈局選項覆蓋合理的需求百分比。

有很多方法可以做到這一點,因此對具體問題領域的一些分析肯定會與對可行方法的研究結合在一起。

儘管直接SQL訪問對用戶來說是最靈活的,但長時間執行的查詢可能只是您頭痛的開始。 SQL注入在這裏是一個大問題,不管它是源代碼是惡意的還是被誤導。

2

除了試圖控制用戶輸入的內容(這是一場失敗的戰鬥,總是會有一個新的僱傭,會產生一個無關緊要的查詢),我會研究資源調控器,請參閱Managing SQL Server Workloads with Resource Governor。您將臨時查詢放入單獨的池中,並限制分配的資源。通過這種方式,您可以通過限制壞查詢對其他任務的損壞數量來緩解問題。

而且您還應該考慮通過其他方式訪問數據,例如Power Pivot,並讓用戶在自己的Excel中按自己想要的方式按摩自己的數據。企業用戶喜歡這一點,並且對交易處理服務器的影響很小。

1

在內部應用程序中的非常大的企業出處這是一種常見的做法。通常在設計階段,您會限制標準或對數據範圍進行明智的限制,但一旦業務獲得應用程序,業務部門管理人員就會打電話來取消限制。在我的起源中,這是一個管理問題,而不是一個工程問題。

我們所做的是分析所有標準,發現最大的違規者,用戶以及哪些類型的查詢導致了最多的問題,並對某些查詢施加了限制。定期使用的一些非常昂貴的查詢也添加到應用程序中,應用程序緩存結果並在加載較低時運行查詢。我們還爲標準用戶創建了caned優化查詢,並僅爲指定用戶提供了搜索任何內容的能力。只是一些想法。

1

您可以爲數據庫創建數據模型,並允許用戶使用SQL Reporting Services的報表生成器。它基於GUI,不需要編寫WHERE子句,所以應該限制他們可以做多少的損害。

或者你可以倉庫分貝用戶查詢的目的副本,更新數據庫每隔一小時左右,讓他們去鎮... :)

0

(乍得在評論中提及了這,但我認爲它應該是一個答案)。

也許你應該將需要特別查詢的數據複製到一個單獨的數據庫中,以隔離大多數用戶的任何問題。

1

我已經工作了幾個地方,這也出現了。我們最終做的事情是不允許用戶不受限制地訪問,並承諾在必要時讓IT盡力提供查詢。問題在於數據庫相當複雜,即使用戶可以在語法和語法上編寫正確的SQL,他們也不一定理解表之間的關係。換句話說,即使他們可以編寫自己的SQL,他們也會得到錯誤的答案。我們說服用戶,基於對數據庫中200張表的錯誤或不完全的理解而做出錯誤決定的風險太高。最好在一天之後得到正確答案,而不是立即得到正確答案。

另一部分是IT在用戶A寫入查詢並獲得1個答案時做了什麼,然後用戶B寫入他認爲是相同的查詢並得到不同的答案?找到差異是IT的工作嗎?要修復這兩個SQL段?等等。底線是我不允許他們訪問。正如其他人提到的那樣,我會使用預定義的查詢加載系統,並嘗試培訓管理人員爲什麼這是長期運行的唯一方式。

1

如果您有這麼多的數據,並且想要向客戶提供分析和查看信息的能力,我強烈建議您提供有關OLAP技術的信息。