2009-06-03 138 views
3

我需要從表中拉幾行並處理它們在兩個方面:一個SQL查詢,或許多循環?

  • 聚集在關鍵
  • 行由行,有相同鍵

表排序看起來大致是這樣的:

table (
    key, 
    string_data, 
    numeric_data 
) 

因此,我正在尋找兩種方法來編寫函數。

首先將拉動總數據使用一個查詢,然後對每個組行,由行數據的循環中再次查詢(以下是PHP類僞代碼):

$rows = query(
     "SELECT key,SUM(numeric_data) 
     FROM table 
     GROUP BY key" 
    ); 

foreach ($rows as $row) { 
    <process aggregate data in $row> 

    $key = $row['key']; 
    $row_by_row_data = handle_individual_rows($key); 
} 

function handle_individual_rows($key) 
{ 
    $rows = query(
      "SELECT string_data 
      FROM table WHERE key=?", 
      $key 
     ); 

    <process $rows one row at a time> 

    return $processed_data; 
} 

或者我可以做一個大的查詢,並讓代碼完成所有的工作:

$rows = query(
    "SELECT key, string_data, numeric_data 
    FROM table" 
); 

foreach ($rows as $row) { 
    <process rows individually and calculate aggregates as I go> 
} 

性能是不是在這個應用的實際的關注;我只是想編寫明智和可維護的代碼。

我喜歡第一個選項,因爲它更模塊化 - 我喜歡第二個選項,因爲它看起來結構簡單。是一種選擇比另一種更好還是它只是一種風格問題?

回答

12

一個SQL查詢,當然。

這將

  • 爲您節省大量的往返到數據庫
  • 允許使用更有效的GROUP BY方法

由於您的聚集可以通過數據庫中的表現同樣出色,它也將更好的可持續性:你將所有的結果集邏輯集中在一個地方。

這裏是返回每一行並計算查詢的一個例子的SUM

SELECT string_data, numeric_data, SUM(numeric_data) OVER (PARTITION BY key) 
FROM table 

注意,這將最有可能使用並行訪問來計算SUM的針對不同key的,這幾乎是可在PHP中實施。

MySQL相同的查詢:

SELECT key, string_data, numeric_data, 
     (
     SELECT SUM(numeric_data) 
     FROM table ti 
     WHERE ti.key = to.key 
     ) AS key_sum 
FROM table to 
+0

「允許使用更高效的GROUP BY方法」 - 怎麼樣?也許這個例子並不清楚,但如果我只使用一個SQL查詢,我認爲我可以*不使用GROUP BY,因爲我需要查看每一行 – 2009-06-03 18:08:07

+1

您需要查看每一行並計算聚合。您正在使用GROUP BY,但使用您自己的GROUP BY。用PHP編寫的你的HASH TABLE幾乎不會比用C編寫的SQL Server更高效。 – Quassnoi 2009-06-03 18:10:09

+0

你能告訴我一個查詢的例子,它可以讓我每一行*和*計算聚合?你在想自己加入嗎? – 2009-06-03 18:15:34

0

如果性能是不是一個問題,我會去與第二。看起來最小的一點友好。

如果表現是一個問題,我的答案是"don't think, profile"。 :)

0

第二個答案是更加清晰,明智和可維護。你用更少的代碼來表達同樣的東西,通常更好。

而且我知道你說過性能不是問題,但爲什麼要獲取數據超過你的要求?

0

我不能確定這裏的例子,但我想知道是否有機會在SQL查詢本身中進行聚合其他處理。在這種情況下,您必須針對您的相對舒適度評估「更易維護」,以表示SQL代碼與PHP代碼中的處理。

是否有什麼關於您需要對每行進行的附加處理,以防止您在SQL查詢本身中表達所有內容?

0

我不認爲你會發現許多情況下,做一個循環查詢每迭代是更好的選擇。其實,我會說這可能是一個很好的經驗法則,從來沒有做到這一點。

換句話說,到數據庫的往返次數越少越好。

根據您的數據和實際表格,您可能可以讓SQL執行聚合工作,並通過一個查詢選擇所需的所有行。

0

一個sql查詢可能是一個更好的主意。 它避免了你不得不重寫關係操作

0

我覺得你已經回答了你自己的問題,因爲你說你有兩個不同的處理:一個聚合和一個接一個行。

  • ,如果你想保留一切可讀性和可維護性,兩者混合在一個查詢中不健全的權利,查詢將回答兩個不同的需求,所以它不會是非常可讀

  • 即使

    如果PERF是不是一個問題,它的速度更快做DB服務器上的聚集,而不是

  • 只有一個查詢做它的代碼,將處理結果將混合兩個處理的代碼,處理行和計算彙總在同一時間,所以在這段代碼將會變得混亂和錯誤

  • 相同的代碼可能會隨着時間的推移,比如行由行可能會很複雜,並可能在凝聚部或周圍的其他方法

  • 創建錯誤如果將來你需要拆分這兩種治療方法,這將是很難解開,在那一刻,別人已經很久很久以前寫的代碼...

性能方面的考慮之外,在可維護性和可讀性,我建議的條款使用兩個查詢。

但是請記住,業績因素可能不是目前的問題,但它可以在時間一旦分貝量的增長或什麼的,它永遠不會在長期內可以忽略不計的因素...

0

即使perf不是問題,你的思想是。當一個音樂家練習每一個動作都是爲了提高音樂家的技巧。作爲一名開發者,你應該開發每一個程序來提高你的技能。迭代循環,雖然數據是sl and和醜陋的。 SQL查詢很優雅。你想開發更優雅的代碼或更粗糙的代碼?