[英]How to improve MySQL query with JOINED tables and ORDER BY and OFFSET
games_releases
是一個包含游戲信息的表。 諸如游戲名稱,游戲發行者或開發者之類的信息對於許多不同的游戲都是相同的,因此它們被保存在不同的表中,這些表隨后結合在一起。
下面的示例僅將games_titles
表聯接games_titles
,以便於理解(但實際上,按照相同的原理聯接了一些表)。
games_releases
表:
id int(11) <- unique
title_id int(11) <- index
developer_id int(11)
... more game relevant data
games_releases
一些典型行如下所示:
id title_id developer_id ... ...
--------------------------------------------
1 17 265
2 23 41
3 31 3
4 42 15
5 17 123
games_titles
表:
id int(11) <- unique
title varchar(128)
created int(11)
一些典型的games_titles
行如下所示:
id title created
----------------------------------------
17 Pac-Man [some unix timestamp]
23 Defender [some unix timestamp]
31 Scramble [some unix timestamp]
42 Q*bert [some unix timestamp]
99 Phoenix [some unix timestamp]
現在:假設用戶希望按字母順序(一次24個)查看所有游戲,那么將執行此查詢...
SELECT
id AS release_id, t.`title` AS title
FROM
games_releases
LEFT JOIN games_titles t ON t.`id`=`games_releases`.`title_id`
ORDER BY title
LIMIT 24
這將被退回
release_id title
-----------------------------
2 Defender
1 Pac-Man
5 Pac-Man
4 Q*Bert
3 Scramble
因此,基本上,結果表以字符串而不是id為特征。
挑戰:此查詢將需要0.2秒才能運行,這很慢( games_releases
列出了大約80.000個項目,但是假設數據庫增長到1.000.000個項目)。
這是解釋告訴我的內容(games_releases具有索引title_id):
id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE games_releases NULL index NULL title_id 4 NULL 76669 Using index; Using temporary; Using filesort
1 SIMPLE t NULL eq_ref PRIMARY PRIMARY 4 phoenix.games_releases.title_id 1
有機會進行優化嗎?
編輯:問題已得到解答。 錯誤的是“ LEFT JOIN”而不是“ JOIN”。
但是:隨着偏移量的增加,我將如何征服更長的執行時間?
盡管已經閱讀了很多文章,但我仍然難以理解在執行多個JOIN時如何有效地設置索引。
為games_titles建立一個“ title”索引似乎沒有任何作用。
供將來參考:有關查詢性能的問題通常必須提供查詢中涉及的每個表的SHOW CREATE TABLE tablename
的輸出。 表結構會影響性能。
從您的查詢看來,它看起來像是games_titles
字母順序顯示games_titles
表中的前24個標題,而games_titles
表中根本沒有任何匹配games_releases
。 不過,我不了解您的LEFT JOIN
的邏輯。 如果games_releases
的標題行多於一列,您是否要重復標題? 您要對games_releases
中的行與games_titles
的行不匹配的行games_titles
什么?
我認為您可以得到想要的結果,如下所示:
SELECT DISTINCT t.id, t.title
FROM games_titles t
JOIN games_releases r ON t.id = r.title_id
ORDER BY t.title
LIMIT 24
這樣,標題表中的行就可以與發布表中的任何內容相匹配。 這可能是最佳的性能。 但是,我想知道應用程序中的前24個標題(按字母順序)有什么重要意義,以及為什么在視圖中這么重要?
SELECT lots, of, stuff .... ORDER BY something LIMIT number
是一個臭名昭著的性能反模式。 為什么? MySQL必須對大量數據進行排序,而只是丟棄少量數據。 視圖定義的局限性使您很難在視圖中執行更有效的操作。
您沒有告訴我們是否將games_titles.id
編入索引。 它需要索引。 如果它是主鍵,它將被索引。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.