[英]How can I optimise this MySQL query?
我在包含超過300,000,000(是,三億)行的數據庫的PHP腳本中使用以下MySQL查詢。 我知道這是非常耗費資源的,運行這一個查詢需要很長時間。 有誰知道如何優化查詢或以更快的方式獲取信息?
我需要能夠使用1到15之間的任何整數代替MID()中的14。 我還需要能夠在LIKE
子句中匹配相同范圍內的長度字符串。
表信息:
games | longint, unsigned, Primary Key
win | bit(1)
loss | bit(1)
示例查詢:
SELECT MID(`game`,14,1) AS `move`,
COUNT(*) AS `games`,
SUM(`win`) AS `wins`,
SUM(`loss`) AS `losses`
FROM `games`
WHERE `game` LIKE '1112223334%'
GROUP BY MID(`game`,1,14)
在此先感謝您的幫助!
首先,在游戲領域有一個索引...... :)
查詢看起來簡單明了,但它隱藏了可能需要更改數據庫設計的事實。
在這種情況下,我總是喜歡維護一個包含聚合數據的字段,每天,每個用戶或任何其他軸。 這樣,您可以擁有聚合相關數據並將其保存在數據庫中的日常任務。
如果您經常調用此查詢,則應使用降低插入效率的原則來提高檢索效率。
看起來game
列存儲了此查詢正在使用的兩個(或可能更多)不同的內容:
game
開始時過濾(前10個字符) MID(
游戲,1,14)
(我假設其中一個MID
表達式是拼寫錯誤。 我將其拆分,以便您不必在game
列上使用字符串操作,並在新列上放置索引,以便您可以正確地過濾和分組它們。
這個查詢正在進行大量的轉換(長到字符串)和字符串操作,如果表是規范化的(如每列中的一條信息而不是像現在這樣的多條信息)。
將game
列保留game_filter
,並根據它創建一個game_filter
字符串列,以便在WHERE子句中使用。 然后設置一個game_group
列,並在插入時使用MID
表達式填充它。 將這兩列設置為聚簇索引,首先是game_filter
,然后是game_group
。
查詢很簡單,除了確保有所有必要的索引(顯然是“游戲”字段)之外,通過僅重寫查詢可能沒有明顯的方法使其更快。 可能需要對數據結構進行一些修改。
一種方法:預先計算總和。 這些記錄中的每一個都很可能具有create_date或自動增量的鍵字段。 預先計算所有記錄的總和,此字段≤X,將結果放入邊表,然后您只需計算所有記錄> X,然后用預先計算的結果匯總這些部分結果。
您可以預先計算MID( game
,14,14)和MID( game
,1,14),並將game
的前十位數存儲在一個單獨的game
列表列中,該列被編入索引。
調查是否可以只存儲預先計算的值的聚合表,以便在插入時增加計數和贏或輸列列也可能是一個想法。
SELECT MID(`game`,14,1) AS `move`,
COUNT(*) AS `games`,
SUM(`win`) AS `wins`,
SUM(`loss`) AS `losses`
FROM `games`
WHERE `game` LIKE '1112223334%'
在game
上創建索引:
CREATE INDEX ix_games_game ON games (game)
並重寫您的查詢,如下所示:
SELECT move,
(
SELECT COUNT(*)
FROM games
WHERE game >= move
AND game < CONCAT(SUBSTRING(move, 1, 13), CHR(ASCII(SUBSTRING(move, 14, 1)) + 1))
),
(
SELECT SUM(win)
FROM games
WHERE game >= move
AND game < CONCAT(SUBSTRING(move, 1, 13), CHR(ASCII(SUBSTRING(move, 14, 1)) + 1))
),
(
SELECT SUM(lose)
FROM games
WHERE game >= move
AND game < CONCAT(SUBSTRING(move, 1, 13), CHR(ASCII(SUBSTRING(move, 14, 1)) + 1))
)
FROM (
SELECT DISTINCT SUBSTRING(q.game, 1, 14) AS move
FROM games
WHERE game LIKE '1112223334%'
) q
這將有助於更有效地使用game
索引。
你可以用Memcache或類似的東西緩存結果集嗎? 這將有助於重復點擊。 即使您只將結果集緩存幾秒鍾,也可以避免大量的數據庫讀取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.