2016-01-19 28 views
0

我對我的數據庫使用MySQL,並且在數據庫端做了一些處理,以使我的應用程序更加輕鬆。獲得性能並執行快速sql查詢的最佳方法?

我以前的查詢速度非常快,直到最近我的數據庫有很多數據,查詢速度非常非常慢。

我的應用程序主要做統計,並有很多相關的數據庫來獲取數據。

下面是一個例子:

tbl_game

 
+-------------------------------------+ 
|  id | winner | duration| endedAt | 
|--------+--------+---------+---------| 
|  1 |  1 | 1200 |timestamp| 
|  2 |  0 | 1200 |timestamp| 
|  3 |  1 | 1200 |timestamp| 
|  4 |  1 | 1200 |timestamp| 
+-------------------------------------+ 

贏家是誰贏得了比賽 時間球隊0或1的秒數場比賽耗時

tbl_game_player

 
+-------------------------------------------------+ 
| gameId | playerId | playerSlot | frags | deaths | 
|--------+----------+------------+-------+--------| 
|  1 |  100 |   1 | 24 |  50 | 
|  1 |  150 |   2 | 32 |  52 | 
|  1 |  101 |   3 | 26 |  62 | 
|  1 |  109 |   4 | 48 |  13 | 
|  1 |  123 |   5 | 24 |  52 | 
|  1 |  135 |   6 | 30 |  30 | 
|  1 |  166 |   7 | 28 |  48 | 
|  1 |  178 |   8 | 52 |  96 | 
|  1 |  190 |   9 | 12 |  75 | 
|  1 |  106 |   10 | 68 |  25 | 
+-------------------------------------------------+ 

該細節僅限於第一場比賽的ID爲1 1場比賽有10個球員插槽其中插槽1-5 =隊0和6-10 =隊1 我的真實表中有更多的細節,這只是給一個概述。

所以我需要計算所有遊戲中每個玩家的統計數據。我創建了一個視圖來實現這一點,並且當我有少量數據時它工作正常。

下面是一個例子:

 
+--------------------------------------------------------------------------+ 
| gameId | playerId | frags | deaths | actions | team | percent | isWinner | 
|--------+----------+-------+--------+---------+------+---------+----------| 

行動=斷枝+死亡 百分比=(動作/總和(玩家在同一隊的動作))* 100 團隊使用playerSlot在1,2-計算,3,4,5或6,7,8,9,10 isWinner is the team by winner and winner

這只是1個算法,我還有很多其他的要執行。我的數據庫是1千萬條記錄,查詢速度很慢。

這裏是上面的查詢:

SELECT 
    tgp.gameId, 
    tgp.playerId, 
    tgp.frags, 
    tgp.deaths, 
    tgp.frags + tgp.deaths AS actions, 
    IF(playerSlot in (1,2,3,4,5), 0, 1) AS team, 
    ((SELECT actions)/tgpx.totalActions) * 100 AS percent, 
    IF((SELECT team) = tg.winner, 1, 0) AS isWinner 
FROM tbl_game_player tgp 
INNER JOIN tbl_game tg on tgp.gameId = tg.id 
INNER JOIN (
    SELECT 
     gameId, 
     SUM(frags) AS totalFrags, 
     SUM(deaths) AS totalDeaths, 
     SUM(frags) + SUM(deaths) as totalActions, 
     IF(playerSlot in (1,2,3,4,5), 0, 1) as team 
    FROM tbl_game_player 
    GROUP BY gameId, team 
) tgpx on tgp.gameId = tgpx.gameId and team = tgpx.team 
+0

上述查詢所說的「explain select ....」是什麼意思? –

+0

通常應該說些什麼?有2個主要的,1個派生的和1個依賴的子查詢。我不知道如何閱讀'解釋選擇...'數據。你可以解釋嗎? – user2707590

+0

只是將它們複製到問題中。 –

回答

0

建立索引將加快查詢速度。查詢可能需要一段時間才能運行,如果有很多結果,這絕對是一個開始。

+0

我應該在我的所有領域添加索引嗎?我的意思是我如何繼續知道在哪裏添加索引? – user2707590

+0

@ user2707590不僅在將要用於連接的字段上應用索引。 –

+0

如果一個字段是主鍵或外鍵,我還應該添加一個索引嗎? – user2707590

3

這很明顯,索引不會幫你在這裏¹,因爲你想要全部數據來自兩個表。一旦彙總,您甚至需要兩次來自tbl_game_player的數據,一次不彙總。所以有數百萬條記錄要讀取和加入。你的查詢很好,我看不出真正改善它的方法。

¹當然,您應該始終在主鍵和外鍵上都有索引,因此DBMS可以在連接中使用它們。 (例如,應該有tbl_game(tgp.gameId)的索引)。

所以你的選擇在於查詢外:

  • 硬件(顯然)。
  • 爲團隊添加一個計算列到tbl_game_player,所以至少在查詢時保存它的評估。
  • 分區。每個團隊一個分區,因此可以分別計算總量。
  • 預先計算的數據:添加一個表tbl_game_team持有總和;用觸發器填充它。因此,您不必在查詢中計算聚合。
  • 數據倉庫表:製作一張表,其中包含完整的結果。用觸發器或間隔填充它。
+0

由1,你的意思是,即使我有主鍵或外鍵,我應該創建另一個索引呢? – user2707590

+0

大多數DBMS自動在主鍵和外鍵上創建索引。我也不知道MySQL是否也這麼做。如果沒有,那麼是的,創建它們。 –

-1

對於大型數據庫Mysql INDEX可以在速度問題上非常有幫助,可以在表中創建索引以更快速地找到數據&。所以必須創建索引,你可以在這裏瞭解更多關於MYsql索引的信息http://www.w3schools.com/sql/sql_create_index.asp