SQL 查询在 SSMS 中运行时间过长
Posted
技术标签:
【中文标题】SQL 查询在 SSMS 中运行时间过长【英文标题】:SQL query takes too long to run in SSMS 【发布时间】:2021-03-15 12:28:54 【问题描述】:我有以下查询,它在 Oracle 开发人员中工作得非常好
select TRIM(a.filterh)
from CHANNEL a,GENRE b
where b.label = 'M001CL01_ABC'
and a.s_r_id = b.r_id
and a.filterh in (select c.filterh
from CHANNEL c, GENRE d
where d.label = 'M001AL03' and c.s_r_id = d.r_id)
我只是尝试为 SQL 开发人员简化上面的查询和一些语法更改,而下面的查询需要大量时间才能在 SSMS 中运行
select TRIM(a.filterh)
from CHANNEL a
inner join GENRE b on a.s_r_id = b.r_id
where b.label = 'M001CL01_ABC'
and a.filterh in (select c.filterh
from CHANNEL c
inner join GENRE d on c.s_r_id = d.r_id
where d.label = 'M001AL03')
我只是想了解我在这里做错了什么,如何改进我的查询以及为什么 SQL 查询需要很多时间。
谢谢。
【问题讨论】:
“不”不是很具有描述性。你有错误吗?出乎意料的结果?怎么了?请注意,在这两个数据库中,可能有比这里所做的更好的方法。 @GordonLinoff 我已经更新了我的问题,你能告诉我什么是 SQL 查询的更好方法吗? 这将有助于查看表模式和现有索引。in
子句看起来很可疑,可能只用 exists
替换 Genre
表?
我会尽快发布架构,数据以十万为单位,因此无法发布
请添加表和索引定义,也请通过brentozar.com/pastetheplan分享查询计划
【参考方案1】:
看看EXISTS
而不是IN
是否能更好地改善这种情况。
select TRIM(a.filterh)
from CHANNEL a
inner join GENRE b on a.s_r_id = b.r_id and b.label = 'M001CL01_ABC'
where exists(select *
from CHANNEL c
inner join GENRE d on c.s_r_id = d.r_id and d.label = 'M001AL03'
where a.filterh = c.filterh)
【讨论】:
我知道Exists
,但您能帮我了解一下我的查询中的a.filterh in
部分在您的版本中是如何处理的
@m_beta,它被移动到内部查询的where
部分。【参考方案2】:
看起来您可能可以执行以下操作,如果没有看到数据并能够进行测试,很难确定:
select TRIM(a.filterh)
from CHANNEL a
inner join GENRE b on a.s_r_id = b.r_id
where b.label = 'M001CL01_ABC'
and exists (select * from GENRE g where g.r_id=a.s_r_id and g.label='M001AL03')
【讨论】:
【参考方案3】:这是我的查询版本。请记住,由于没有要测试的数据,所以我无法正确测试它,所以由您检查它是否可以编译。
这里我所做的只是删除了子查询,因为它们经常导致查询优化器出错
select TRIM(a.filterh)
from CHANNEL a
join GENRE b on a.s_r_id = b.r_id
join CHANNEL c on a.filterh = c.filterh
join GENRE d on c.s_r_id = d.r_id
where b.label = 'M001CL01_ABC'
and d.label = 'M001AL03'
另外一点要提到的是,性能问题可能取决于很多事情。例如行数、索引、存储设备等。如果您以后发布类似的问题,最好在执行查询时向我们提供执行计划和打开的统计信息。
如果查询运行缓慢,ON A TEST INSTANCE 尝试在 channel.filterg 上创建一个索引,在genre.label 列上创建另一个索引。
【讨论】:
这个查询可以执行,只是检查是否能得到想要的输出。我会尽快回复。 @m_beta 如果以上提供的所有解决方案都不适合您,请检查我的更新答案【参考方案4】:我认为您可以在任一数据库中使用聚合:
select TRIM(c.filterh)
from CHANNEL c join
GENRE g
on g.s_r_id = c.r_id
where g.label in ('M001CL01_ABC', 'M001AL03')
group by TRIM(c.filterh)
having count(distinct g.label) = 2;
你应该学会使用有意义的表别名。 a
和 b
等任意字母无助于任何人理解查询。
【讨论】:
以上是关于SQL 查询在 SSMS 中运行时间过长的主要内容,如果未能解决你的问题,请参考以下文章
Postgres 选择查询在使用 JDBC 时运行缓慢,但在从同一服务器在 PSQL 中运行时快速