我有一个SQL查询,它工作,但很慢。我想知道是否有一个更有效的方法来表达它使用连接。
场景:
表:productions
、scripts
和连接表productions_scripts
| productions|
| --|
| id(int)|
| 生产(文本)|
| 脚本|
| --|
| id(int)|
| 脚本(文本)|
| 正则(bool)|
| 制作脚本|
| --|
| id(int)|
| production_id(int)|
| script_id(int)|
要求:
返回产品及其关联脚本的列表,其中产品具有多个“规范”类型的脚本。仅显示脚本为规范的结果。
当前查询:
SELECT productions.id AS production_id, productions.production,
scripts.id AS script_id, scripts.script
FROM scripts, productions, productions_scripts
WHERE productions.id IN (SELECT productions_scripts.production_id
FROM productions_scripts, scripts
WHERE scripts.id = productions_scripts.script_id
AND scripts.canonical = 1
GROUP BY production_id
HAVING COUNT(production_id) > 1
)
AND productions.id = productions_scripts.production_id
AND scripts.id = productions_scripts.script_id
AND scripts.canonical = 1
ORDER BY production_id;
字符串
问题:查询正常,但运行时间较长(约45秒)
我在编写查询时遇到的主要困难是获得多个规范脚本的生产计数,同时需要为每个匹配的生产脚本组合输出一行,而不仅仅是production_id
的唯一值。
看起来我必须使用GROUP BY production_id
来获得计数。但是这也会导致production_id
的唯一值输出。因此需要子查询。
编辑。我发布的查询是错误的版本-它返回了非规范脚本的产品。我在最后一节用AND scripts.canonical = 1
子句更新了它。
4条答案
按热度按时间5us2dqdw1#
下面是一种使用多个
INNER JOIN
子句的方法:字符串
y4ekin9u2#
有适当的索引肯定会有所帮助,因为这些表是基本的,我只是显示,你可以确认
字符串
接下来,你的子查询是在目标上的,但是正如其他人所指出的,使用显式连接而不是逗号表列表。
最后,因为这是从MySQL,我会通过在关键字“STRAIGHT_JOIN”,它告诉MySQL做查询的顺序,我已经列出,不要为我想。我不知道你的数据表大小(记录),但从一个系统,我多年前与20+百万记录链接到25+查找表相应的描述,这一个关键字使一个查询从服务器崩溃到在不到2小时的时间内返回结果。
话虽如此,我会修改为:
型
内部查询依赖于其自身与脚本的连接,以便仅具有任何符合条件的记录的计数> 1。然后,立即将符合条件的生产ID重新连接到其余表以提取相应的详细信息。
plicqrtu3#
可以使用窗口函数代替子查询。
字符串
请注意,您应该使用显式连接语法,而不是逗号=连接。
t3psigkw4#
假设MySQL ≥ 8.0(但考虑到你对Charlieface的答案的挣扎,这是值得怀疑的),并且
p.production
和s.script
都是相当大的文本字段,你可能会从SelVazi和Charlieface展示的方法中受益:字符串