簡體   English   中英

如何使用JOINED表以及ORDER BY和OFFSET改善MySQL查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM