如何使用联接表和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