我有一个类似的查询:
select row_number() over(order by m_time desc) as row, m.m_id, m_time, m_log_id
(case when exists(select 1 from t_approved_phonenumber where phone_number = m.c_phone_number) then 1 else 0 end) as approved,
(case when exists(select 1 from t_log log where log.c_id < m.m_log_id and log.phone_number = m.phone_number) then 'N' else 'Y' end) as is_first_time
from t_message m
所有表t_approved_phonenumber,t_message和t_log都有很多记录。并且所有ID都是主键,phone_number列具有索引。有时我的查询很慢。有没有办法加快速度?
感谢,
答案 0 :(得分:0)
也许在t_log
上使用第一列phone_number
和第二列c_id
制作索引,以便第二列存在可以只使用此索引并依赖于DBMS - 甚至可能没有访问表t_log
本身。声明索引唯一可以促进它对优化器的使用 - 但当然,如果它真的是唯一的,你只能这样做。
当然,如果到目前为止还没有m_time的索引,这可能对row_number()
有帮助。
答案 1 :(得分:0)
尝试使用普通的“左连接”子查询替换相关子查询,因为它们通常表现更好。常规子查询只运行一次,与针对每行运行的相关子查询相反。它也更灵活 - 如果需要,您可以向子查询添加更多数据。 您的查询应如下所示(可能出现错误 - 目前没有Management Studio):
select
row_number() over(order by m_time desc) as row
,m.m_id
,m_time
,m_log_id
,coalesce(approved, 0) as approved
,coalesce(is_first_time, 'Y') as is_first_time
from
t_message m
left join (select phone_number, 1 as [approved] from t_approved_phonenumber group by phone_number) as a
on a.phone_number = m.c_phone_number
left join (select phone_number, min(c_id) as c_id, 'N' as is_first_time from t_log group by phone_number) log
on log.c_id < m.m_log_id and log.phone_number = m.phone_number
答案 2 :(得分:0)
根据我的经验,joins
比谓词中的select更好。
试试这个查询。
我认为对于每个t_message,Phone_Number
中的每个t_message
至少有一次调用,因此我在第二个INNER JOIN
中使用JOIN
而不是左连接
select row_number() over(order by m_time desc) as row,
m.m_id,
m_time,
m_log_id,
(case WHEN approved.phone_number IS NULL then 0 else 1 end) as approved,
(case when First_c_id < m.m_log_id then 'N' else 'Y' end) as is_first_time
from t_message m
LEFT JOIN t_approved_phonenumber approved ON m.c_phone_number = approved.phone_number
INNER JOIN (SELECT phone_number, MIN(c_id) AS First_c_id
FROM t_log
GROUP BY phone_number) FirstLog ON FirstLog.PhoneNumber = m.phone_number
无论如何,@ FrankPl建议的索引可以帮助我们获得更多的性能,