如何使用联接表和ORDER BY和OFFSET改进MySQL查询

如何使用联接表和ORDER BY和OFFSET改进MySQL查询,mysql,optimization,sql-order-by,query-performance,Mysql,Optimization,Sql Order By,Query Performance,games\u releases是一个组合游戏信息的表格。信息就像游戏标题一样,游戏发布者或开发者对于许多不同的游戏都是相同的,因此它们保存在不同的表中,然后再连接在一起 下面的示例仅将games\u titles表连接起来,以便于理解(但实际上,还有几个表按照相同的原则连接起来) games\u发布表格: id int(11) <- unique title_id int(11) <- index developer_id int(

games\u releases
是一个组合游戏信息的表格。信息就像游戏标题一样,游戏发布者或开发者对于许多不同的游戏都是相同的,因此它们保存在不同的表中,然后再连接在一起

下面的示例仅将
games\u titles
表连接起来,以便于理解(但实际上,还有几个表按照相同的原则连接起来)

games\u发布
表格:

id            int(11)     <- unique
title_id      int(11)     <- index
developer_id  int(11)
... more game relevant data
id      int(11)       <- unique
title   varchar(128)
created int(11)
游戏标题
表格:

id            int(11)     <- unique
title_id      int(11)     <- index
developer_id  int(11)
... more game relevant data
id      int(11)       <- unique
title   varchar(128)
created int(11)
现在:假设用户希望按字母顺序(一次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\u releases
列出了大约80.000个项目,但想象一下数据库将增长到1.000.000个项目)

下面是解释告诉我的(游戏发布有一个索引标题\u id):

有机会优化这个吗

编辑:问题已经回答了。问题在于错误的“左连接”而不是“连接”

但是:我该怎么做才能克服随着偏移量增加而延长的执行时间

虽然读了很多关于它的文章,但我很难理解在进行多个连接时如何有效地设置索引


为游戏标题设置“标题”索引似乎没有任何效果。

供将来参考:关于查询性能的问题通常必须显示查询中涉及的每个表的
SHOW CREATE TABLE TABLE name
的输出。表结构对性能有影响

从您的查询来看,似乎您希望按字母顺序显示
games\u titles
表中的前24个标题,其中
games\u releases
表中有任何匹配项。不过,我不明白你的
左连接的逻辑。如果
游戏发布版中的标题有多行,是否希望重复标题?您希望如何处理
games\u发行版
中与
games\u标题
中的行不匹配的行

我想你可以得到你想要的结果如下:

   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
这将提供标题表中与releases表中任何内容匹配的不同行。这可能是最佳性能。不过,我想知道,在应用程序中,按字母顺序排列的前24个标题有什么重要意义,以及为什么在视图中输入这些标题很重要

选择一批、一批、一批。。。。ORDER BY something LIMIT number
是一种臭名昭著的性能反模式。为什么?MySQL必须对大量数据进行排序,但只丢弃了少量数据。视图定义的局限性使您很难在视图中执行更有效的操作


您没有告诉我们是否对
games\u titles.id
进行了索引。它需要索引。如果它是主键,则索引。

可能是游戏发布和游戏标题不匹配???请阅读此内容。请特别注意查询优化部分。那么请您的问题提供更多信息,以便我们能够帮助您。顺便说一下,MySQL查询规划器将视图视为子查询,因此优化视图并不保证外部查询会得到优化。@O.Jones我想我已经这样做了。有问题的问题和解释。我将广告db结构。对。查看索引和数据类型很重要。@O.Jones:Done。我真的尽力把它说得尽可能简单。对不起,如果我不清楚的话。其目的是:games_发布的表格有许多行引用其他表格(规范化)。我想要的是按字母顺序从游戏发布中选择。所以我想从games_发行版中获取行,而不是从games_标题中获取行。games_releases(游戏发布)行包含有关游戏的所有信息,games_titles(游戏标题)仅包含游戏名称。因此,可能会有100个同名的发行版引用games_title表来获取发行版的名称。我在下一次编辑中解释得更好。我已经尽了最大努力在问题中解释得更好。如果您能再看一看,我将非常感激……用内部连接替换左连接(当然在标题列上添加索引)应该能说服MySQL翻转表的顺序并快速处理。我现在正在检查这个问题。这非常有帮助,@peufeu!我不知道我为什么用左键连接!但是我在mysql中也不是很好(正如你现在所知道的)。非常感谢。现在我需要找到一种方法,当有大的偏移量时,使它更快。谷歌是我的朋友!
   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