幸運的是,它通常並不意味着。
在公式中的缺失變量是數據庫和應用程序服務器和其他任何在你的堆棧如何處理concurrency。
爲了從MySQL的角度嚴格地說明這一點,我編寫了一個測試客戶端程序,它建立與MySQL服務器的連接的固定數量,每個連接在它自己的線程中(因此,能夠近似地向服務器發出查詢同一時間)。
一旦所有線程都發回信號表示它們已連接,則會同時向所有線程發送消息以發送其查詢。
當每個線程獲取「go」信號時,它會查看當前系統時間,然後將查詢發送到服務器。當它得到響應時,它再次查看系統時間,然後將所有信息發送回主線程,主線程比較定時並生成下面的輸出。
程序的寫入方式不會計算建立與服務器的連接所需的時間,因爲在性能良好的應用程序中,連接將是可重用的。
查詢結果爲SELECT SQL_NO_CACHE COUNT(1) FROM ...
(一個包含約500行的InnoDB表)。
threads 1 min 0.001089 max 0.001089 avg 0.001089 total runtime 0.001089
threads 2 min 0.001200 max 0.002951 avg 0.002076 total runtime 0.003106
threads 4 min 0.000987 max 0.001432 avg 0.001176 total runtime 0.001677
threads 8 min 0.001110 max 0.002789 avg 0.001894 total runtime 0.003796
threads 16 min 0.001222 max 0.005142 avg 0.002707 total runtime 0.005591
threads 32 min 0.001187 max 0.010924 avg 0.003786 total runtime 0.014812
threads 64 min 0.001209 max 0.014941 avg 0.005586 total runtime 0.019841
時間以秒爲單位。最小/最大/平均是運行相同查詢時觀察到的最佳/最差/平均時間。在併發性爲64時,您注意到最好的情況與僅有1個查詢的最好情況並不完全不同。但是這裏最大的收穫就是總運行時間欄。該值是第一個線程發送查詢的時間差異(它們都基本同時發送查詢,但「恰好」同一時間是不可能的,因爲我沒有64核心的機器來運行測試腳本)到最後一個線程收到響應的時間。
觀察:好消息是,64個查詢服用0.005586秒的平均絕對沒有需要64 *0.005586秒=0.357504秒執行......它甚至沒有需要64 * 0.001089(最好情況下的時間)= 0.069696所有這些查詢都是在0.019841秒內開始和完成的......或者只有理論上他們需要一個接一個地運行的時間的大約28.5%。
當然,壞消息是這個查詢在64個併發時的平均執行時間是僅僅運行一次的5倍以上,而最壞的情況幾乎是14倍一樣高。但是,這仍然比單一查詢執行時間提示的線性外推要好得多。
不過,事情並不會無限縮放。正如你所看到的,隨着併發性的發展,性能會下降,並且在某種程度上它會下降 - 可能相當快 - 因爲我們已經達到了先發生瓶頸的地步。表的數量,查詢的性質,遇到的任何鎖定都會影響服務器在併發負載下的性能,存儲性能,系統內存的大小,性能和體系結構以及MySQL的內部 - 其中一些可以調整,其中一些不能。
但當然,數據庫不是唯一的因素。應用程序服務器處理併發請求的方式可能是負載下性能的另一大部分,有時甚至比數據庫更大,有時甚至更少。
基準測試的一個未知之處是,數據庫應答查詢花費了多少時間,應用服務器執行邏輯業務需要花費多少時間,以及花了多少時間將頁面結果呈現爲HTML的代碼。
謝謝邁克爾,你正是我所需要的,這意味着確切的數據庫查詢部分。我現在睡得更好,知道你剛剛發佈的這些數據:)再次感謝徹底:) –