2011-06-17 29 views
3

我們目前正在調查對我們的SQL服務器的負荷,並尋找方法來減輕它。在我的專上教育期間,我總是被告知,從性能的角度來看,讓SQL Server做這項工作更便宜。但這是真的嗎?性能的SQL函數與代碼的功能

下面是一個例子:

SELECT ord_no FROM oelinhst_sql 

這在14秒之返回783119條記錄。該場是一個char(8),但所有的訂單號碼是六位數所以每個有兩個空白字符領先。我們通常修剪這個領域,所以我跑瞭如下測試:

SELECT LTRIM(ord_no) FROM oelinhst_sql 

這13秒鐘內返回的783119條記錄。我也嘗試了第二次檢查:

SELECT LTRIM(RTRIM(ord_no)) FROM oelinhst_sql 

沒有什麼修剪就沒事了,但我想看看是否有在調用該函數的僅僅是行爲的任何開銷,但它仍然13秒鐘內返回。

我的經理在談論移動之類的字符串修剪出來的SQL,進入源代碼,但測試結果並非如此。我的經理也說,他聽說使用SQL函數意味着索引不會被使用。這是否有任何事實?

+1

哪個服務器您使用的是? SQL Server,Oracle,MySQL ...... – Tony

+4

使用SQL Server的系統最慢的部分將是您的磁盤訪問。任何會減少從磁盤讀取的數據都會(通常)加快查詢速度。因此,從SQL讀取*一切*然後在代碼中處理它不會有太大的幫助。 – Tony

+2

在你的例子中,由於沒有任何'WHERE'子句,因此不會使用任何索引。您的經理可能會說,如果您有一個像「SELECT ... WHERE LTRIM(ordno)= 17'這樣的子句,那麼仍然不會使用索引。這可能是真的_unless_你也有一個計算列的功能索引或索引[不同的RDBMS有不同的做法]。 –

回答

3

只有優化您已經被證明是你的系統最慢的部分代碼。到目前爲止,您的數據表明SQL字符串操作函數根本不會影響性能。把這些數據提交給你的經理。

如果您在WHERE子句中使用函數或類型轉換它往往可以防止SQL服務器使用索引。這不適用於使用函數轉換返回的列。

+1

雖然我同意你的回答的意圖,但如果變換停止使用[覆蓋索引](http:// en。),則「這不適用於用函數轉換返回的列」的說法在技術上並不正確。 wikipedia.org/wiki/Index_(database)#Covering_Index)。 –

+1

你是對的。如果查詢否則將使用僅索引計劃,則在變換列後將無法進行。你可以通過子查詢來解決這個問題,在外部查詢中進行轉換。 –

0

這一定程度上取決於什麼都被涵蓋「之類的字符串微調」,但是,對於字符串微調至少,我肯定讓數據庫做(會減少網絡流量以及)。至於指標,他們仍然會如果你where子句只是使用列本身(而不是列的一個功能)使用。使用索引不會影響您在檢索的實際列上使用函數(僅限於您如何選擇行)。

你可能想看看這個性能改進建議:http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/

+0

對於這個問題,SELECT ord_no FROM oelinhst_sql需要14秒**才能返回〜750000行,這表明可能已經有索引問題需要解決。 .. –

1

這是典型的用戶定義函數(UDF),其獲得一個壞名聲與問候到SQL的性能,並且可能建議你的源正在得到。

這樣做的原因是,你可以建立會導致指數影響巨大的開銷,一些漂亮的毛茸茸的功能。

正如您所用RTRIM發現LTRIM這不是一個毯子原因停止使用SQL一邊的所有功能。

0

正如我在我的評論說,減少每個查詢讀取數據,你會得到一個的速度增加。

你說:

的訂單號碼是六位數 所以每個有兩個空白字符 領先

讓我覺得你是保存數字的字符串,如果是的話,爲什麼你沒有使用數字數據類型嗎?需要6位數字的最小數字類型是INT(我假設SQL Server),並且已經爲每個訂單號碼節省了4個字節,而在您提到的行數上,這是相當少的數據,以讀取磁盤併發送通過網絡。

在查看數據庫之外的數據之前,先充分優化您的數據庫;這是數據庫服務器設計的目的,可以提供數據。

+0

不幸的是,我們無法對數據庫設計進行更改,因爲我們的ERP系統是由第三方開發的。我們只是建立應用程序,以補充缺乏或不存在的功能。 – Scott

+0

這是不幸的,你不能做出改變,因爲我認爲數據庫本身就是你會看到最大收益的地方。祝你好運,繼續做你開始做的事,測試你的想法,以確保你會看到改善;不要只相信你的老闆告訴你關於數據庫的東西:) – Tony

+0

根據SQL Profiler,大部分問題確實在ERP系統代碼中。我希望能夠與供應商建立合作關係,最終讓他們至少在一定程度上解決這個問題。關於我的老闆,他很坦然地承認他並不知道所有事情,並且完全向船員詢問堆棧溢出和服務器故障。 :-) – Scott

0

正如你發現它經常值得衡量,但我認爲你的經理可能一直指的是這樣的事情。

這是典型的要快得多

SELECT SomeFields FROM oelinhst_sql 
WHERE 
    datetimeField > '1/1/2011' 
    and 
    datetimeField < '2/1/2011' 

比這

SELECT SomeFields FROM oelinhst_sql 
WHERE 
    Month(datetimeField) = 1 
    and 
    year(datetimeField) = 2011 

即使返回的行相同