2011-01-14 61 views
0

這是目前我的MySQL UPDATE查詢,這是從用Java編寫的程序中調用:優化的MySQL更新查詢

String query = "UPDATE maxday SET DatePressureREL = (SELECT " + 
    "Date FROM ws3600 WHERE PressureREL = (SELECT MAX" + 
    "(PressureREL) FROM ws3600 WHERE Date >= '" + Date + 
    "') AND Date >= '" + Date + "' ORDER BY Date DESC LIMIT 1), " + 
    "PressureREL = (SELECT PressureREL FROM ws3600 WHERE " + 
    "PressureREL = (SELECT MAX(PressureREL) FROM ws3600 " + 
    "WHERE Date >= '" + Date + "') AND Date >= '" + Date + 
    "' ORDER BY Date DESC LIMIT 1), ..."; 

try { 
    s.execute(query); 
} 
catch (SQLException e) { 
    System.out.println("SQL error"); 
} 
catch(Exception e) { 
    e.printStackTrace(); 
} 

讓我先解釋一下,這是什麼做的。我有兩個表格,第一個是ws3600,它包含了列(Date,PressureREL,TemperatureOUT,露點,...)。然後我有第二個表,名爲maxday,它包含DatePressureREL,PressureREL,DateTemperatureOUT,TemperatureOUT等列。現在,您可以從示例中看到,我更新每列,問題是,有沒有更快的方法?我在問這個,因爲我打了兩次MAX,先找到該值的日期,然後找到實際值。現在我知道我可以寫這樣的:

SELECT Date, PressureREL FROM ws3600 WHERE PressureREL = 
    (SELECT MAX(PressureREL) FROM ws3600 WHERE Date >= '" + 
    Date + "') AND Date >= '" + Date + "' 
ORDER BY Date DESC LIMIT 1 

這樣,我得到了最大,並在同一時間的最大值的日期,然後用這些值更新maxday表中的數據。但是這個解決方案的問題是,我必須執行很多查詢,根據我的理解,與執行一個長mysql查詢相比,需要更多的時間,因爲在將每個查詢發送到服務器時會有開銷。

如果沒有更好的辦法,我應該選擇哪種解決方案。第一個查詢只接受一個查詢,但未優化,或者第二個查詢優化,但需要更多的查詢,這可能意味着因爲向服務器發送每個查詢而導致性能增益丟失。

+0

爲時已晚上週五晚上對我來說,甚至開始讓我的頭這一個圍繞:P – 2011-01-14 21:45:00

+0

關於第二條日期,我特地到一些Serinus指出,來到一後我可能不需要這樣的結論,因爲我用DESC LIMIT 1限制了結果。它只是沒有第二個子句而沒有DESC LIMIT 1,它將返回與整個表中MAX值相等的所有值,而不僅僅是那些受參數Date限制的人。不過,我想知道我的問題真正的答案。 – 2011-01-14 22:12:38

回答

1

做2個查詢對我來說不是一個真正的問題,但它們應該在事務中(讀和寫),這樣你就可以確定你的更新值沒有錯。有一個查詢,你沒有這個問題。

我認爲在讀取某些數據時丟失的時間與執行寫入操作所浪費的時間無關。寫操作的定義並不是一件快事,你可能有觸發器,你可能會從影響這個表的所有請求中清空查詢緩存,數據庫需要同步你在磁盤上的寫入等。

對你來說更重要的是保持你的過程簡單,可讀和邏輯。

0

從裏到外工作,它看起來像你所有的子查詢做同樣的事情。

使用Date> ='「+ Date +」')AND> Date'='「+ Date +」'的where子句有什麼意義?

不用進入列名或技術細節,你的兩個表的目的是什麼? (選擇MAX(PressureREL)FROM ws3600 WHERE Date> = @Date)AND日期> = @DATE ORDER BY日期DESC LIMIT 1) ,PressureREL =(SELECT PressureREL FROM ws3600 WHERE PressureREL =(SELECT MAX(PressureREL)FROM ws3600 WHERE Date> = @Date)AND Date> = @DATE ORDER BY Date DESC LIMIT 1),...「;

在此之後,理想情況下,如果你正在使用某種類型的,而不是一個字符串的SelectCommand中,你會

query.Parameters.Add(新了MySQLParameter( 「@日」,yourdate));

或者,你可以做到這一點,雖然它可能讓你受到SQL注入

查詢= query.replace( 「@日」, 「 '」 +日期 「'」);

無論哪種方式,它使查詢更清晰。

+0

另外,這可能有助於可讀性。 C#中的字符串之前的@符號將允許您在多行中包含字符串。 – Serinus 2011-01-14 21:00:23

+0

我需要兩個條款檢查日期,第一個條款限制選擇相對壓力的時間,檢查日期的內部條款是在有限時間內選擇MAX。 – 2011-01-14 21:18:47

1

1)我認爲這個問題比SQL優化更深入。你認爲這可以用不同的方式進行建模:你不需要像這樣遷移數據(這很多,而且這往往太順道)首先呢?也許只是使用FK /交叉表將兩者連接在一起而不是遷移每個字段?

2)一個查詢比使用JDBC來更新與新語句的連接來得更好。這是一項非常昂貴的操作(每次)。你總是希望堅持把查詢集中到一箇中,而不是使用迭代來執行許多語句。

0

如果您可以在一個select查詢中獲取所有值,則可能會有效。使用存儲的過程接受一個參數(日),其作用:

一個選擇語句,存儲在光標的值,和

一個更新語句中,使用光標的值。

Cursor Example