我有 sql
查询:
SELECT tsc.Id
FROM TEST.Services tsc,
(
select * from DICT.Change sp
) spc
where tsc.serviceId = spc.service_id
and tsc.PlanId = if(spc.plan_id = -1, tsc.PlanId, spc.plan_id)
and tsc.startDate > GREATEST(spc.StartTime, spc.startDate)
group by tsc.Id;
这个查询非常非常慢。
解释:
这能优化吗?如何为另一个子查询重写此子查询?
1条答案
按热度按时间gopyfrb31#
这个问题有什么意义?为什么要交叉连接操作?为什么我们需要返回多个副本
id
列自Services
table?我们怎么处理被退回的数百万行呢?如果没有一个规范,一组实际的结果集需求,我们只是在猜测。
回答您的问题:
是的,通过将查询重写为实际需要的结果集,可以对查询进行“优化”,并且比问题中可怕的sql更有效。
一些建议:抛弃join操作的老式逗号语法,使用
JOIN
改为关键字。如果没有连接 predicate ,则是“交叉”连接。从一侧匹配到右侧匹配)我建议包括
CROSS
关键字作为对未来读者的指示ON
子句中的连接 predicateWHERE
是故意的,而不是疏忽。我也会避免使用内联视图,除非有特定的原因。
更新
问题中的查询将更新为包含一些 predicate 。根据更新后的查询,我会这样写:
通过查看
EXPLAIN
查看执行计划,特别是正在使用哪些索引。注意事项:
如果中有多行
spc
“匹配”来自tsc
,查询将返回重复的tsc.id
. (不清楚为什么或者是否需要返回重复的值。如果我们需要计算每本书的份数tsc,id
,我们可以在查询中这样做,返回tsc.id
还有一个伯爵。如果我们不需要重复的,我们可以返回一个不同的列表。GREATEST
函数将返回NULL
如果任何参数为null。如果我们需要的条件是a > GREATEST(b,c)
,我们可以指定a > b AND a > c
".此外,这种情况:
可以重写以返回一个等价的结果(我怀疑实际的规范,以及这个原始条件是否充分满足这个条件)。没有示例数据和预期输出的示例,我们只能依赖sql作为规范,因此我们在重写时尊重这一点。)
如果我们不需要返回
tsc.id
,假设id
是独一无二的TEST.Services
,我们也可以写