2011-06-21 124 views
2

我有一個包含三個字段的數據庫(MySQL)表:id,score和percent。SQL語句中計算的速度

長話短說,我需要做的每一個看起來像這樣的記錄計算:

(得分* 10)/(1 - 百分比)=價值

然後我需要使用在我的代碼和ORDER BY字段中都是值。編寫SQL不是我的問題 - 我只是擔心這個聲明的效率。在我的SQL語句中做這種計算是最有效的資源利用方式,還是我會更好地獲取數據,然後通過PHP進行數學計算?

如果SQL是最好的辦法,是否有任何提示,我可以記住保持我的SQL拉儘可能快?

更新1:只是爲了澄清一些事情,因爲它看起來像許多答案都假設不同:分數和百分比都會不斷變化。實際上,幾乎每次用戶與應用程序交互時,這些字段都會改變(這些字段實際上與用戶相關聯,順便說一句)。至於記錄的數量,現在它非常小,但我想要爲約200萬條記錄(用戶)的目標集合進行縮放。在任何給定時間,我只需要20個記錄,但我需要它們成爲按此計算值排序的前20條記錄。

+1

您可以使用此值將另一個字段添加到數據庫中,在添加或更新數據時計算它。你有基準測試需要多長時間? – 2011-06-21 20:21:20

+0

使用MySQL的「解釋」函數來查看時間執行。 – FinalForm

回答

4

這聽起來像這個計算值是在您的業務領域的固有含義;如果是這種情況,我會計算一次(例如創建記錄時),並像使用普通字段一樣使用它。這是實現您想要的最有效的方法 - 插入或更新時的額外計算對性能影響最小,從此您不必擔心計算的是誰。 缺點是您必須更新「插入」和「更新」邏輯才能執行此計算。我通常不喜歡觸發器 - 它們可能是不可逾越的錯誤的來源 - 但這是我認爲它們的一種情況(http://dev.mysql.com/doc/refman/5.0/en/triggers.html )。

如果由於某種原因你不能這樣做,我會建議在數據庫服務器上這樣做。這應該是相當活潑的,除非你處理的記錄數量非常大;在這種情況下,「排序」將是一個真正的性能問題。如果你在PHP端執行相同的邏輯,這將是一個更大的性能問題 - 當然,從性能角度來看,數據庫往往是瓶頸,所以影響更大。 如果你正在處理大量的記錄,你可能只需咬下子彈,並與我的第一個建議。

如果不是需要按計算進行排序,您也可以在PHP端執行此操作;然而,在PHP中對數組進行排序並不是我想要爲大型結果集所做的事情,而且在數據庫中進行排序似乎很浪費(這很好)。

所以,在這一切之後,我的實際建議歸結爲:

  • 做可以工作
  • 測試最簡單的事情無論是速度不夠快你 項目的約束範圍內
  • 如果不是,迭代重構爲更快的解決方案,重新測試
  • 一旦你達到「足夠好」,繼續前進。

基於編輯1

你已經回答了你自己的問題,我認爲 - 返回(最終)2萬行到PHP,才發現前20名的記錄(計算後的「價值「一個接一個)會非常慢。所以在PHP中計算真的不是一種選擇。

所以,你要在服務器上計算它。我的建議是創建一個視圖(http://dev.mysql.com/doc/refman/5.0/en/create-view.html),它有SQL來執行計算;使用200,200K和2M記錄對視圖的性能進行基準測試,並查看它是否足夠快。

如果2M用戶/記錄的速度不夠快,您可以隨時創建一個常規表格,在您的「值」列中有一個索引,而在您的客戶端代碼中相對較少需要更改;您可以通過觸發器填充新表,並且客戶端代碼可能永遠不會知道發生了什麼。

+0

這聽起來像只是添加另一個數據庫字段可能是答案。這個領域將會發生很大的變化,這就是爲什麼我首先想到在飛行中計算它會更好,但現在我有第二個想法。我在我的問題中提供了一些更新的信息:這是否有助於縮小某種解決方案的範圍? – jwegner

0

測試一下,讓我們知道性能結果。我認爲這將取決於結果集中的數據量。對於SQL位,只要確保where子句有一個覆蓋索引。

0

你在哪裏做數學不應該太重要。無論哪種方式,這都是同樣的基本操作。現在,如果MySQL在與您的PHP代碼不同的服務器上運行,那麼您可能會關心哪個CPU進行計算。您可能希望SQL服務器執行更多「艱苦的工作」,或者您可能希望離開SQL服務器執行「僅SQL」,並將數學邏輯移至PHP。

另一個考慮因素可能是帶寬使用(如果MySQL與PHP不在同一臺機器上運行) - 您可能希望MySQL返回哪個表單更短,以便使用更少的網絡帶寬。

但是,如果它們都在同一個物理硬件上,那麼從CPU使用率的角度來看,它可能沒有明顯的區別。

我會提供的一個提示是對原始值(百分比)執行ORDER BY而不是計算值 - 這樣MySQL可以使用百分號列上的索引 - 它不能使用索引計算值。

0

如果你有越來越多的記錄,你的腳本(和它的內存)將會比mysql更快地達到它的極限。您是否打算取回所有記錄? 一般而言,Mysql會更快。 我不明白你將如何使用在PHP中計算的值在ORDER BY之後。如果你打算在PHP中進行排序,它會變得更慢,但這一切都取決於你正在處理的記錄數量。

1

在做數學數據庫的效率會更高因爲發送數據從數據庫中來回的客戶會比簡單的表達慢無論客戶端是多麼快,多麼慢數據庫。

+0

他的查詢不涉及任何「來回」..他只會發送一次數據。此外,您聲稱「不管客戶端速度有多快,數據庫速度有多慢」都沒有區別,只是錯誤。在他的情況下,這可能是真的,但「不管」僅僅是誇大其詞。假設他想計算MD5總和......這是一個非常複雜的操作,無法在SQL語句中輕鬆表達(當然,它可能在存儲過程中,在大多數數據庫引擎中)。 – Flimzy

+0

我的意思是「通過管道將數據發送到客戶端」與「幾種算術運算」相比較。我不是在談論因素分析大素數:)希望澄清。 –