[英]SQL query on large tables fast at first then slow
下面的查询快速返回初始结果然后变得非常慢。
SELECT A.Id
, B.Date1
FROM A
LEFT OUTER JOIN B
ON A.Id = B.Id AND A.Flag = 'Y'
AND (B.Date1 IS NOT NULL AND A.Date >= B.Date2 AND A.Date < B.Date1)
表A有2400万条记录,表B有50万条记录。
表A的索引位于列:Id和Date
表B的索引在列上:Id,Date2,Date1 - Date1可为空 - 索引是唯一的
第一个11米的记录返回得非常快,然后突然变得非常慢。 执行计划显示使用了索引。
但是,当我删除条件A.Date <B.Date1时,查询再次变快。
你知道应该怎样做才能提高性能吗? 谢谢
更新:我更新了查询以显示结果中需要表B的字段。 当我有条件“B.Date1不为空”时,您可能会想到为什么我使用左连接。 那是因为我发布了简化查询。 我的性能问题即使是这个简化版本。
您也许可以尝试使用EXISTS
。 它应该更快,因为一旦发现匹配,它停止寻找更多行,而不像JOIN
那样必须获取和连接所有行。
select id
from a
where flag = 'Y'
and exists (
select 1
from b
where a.id = b.id
and a.date >= b.date2
and a.date < b.date1
and date1 is not null
);
通常我已经注意到了查询,SQL性能是你加入的DATA,例如ONE to ONE
关系比ONE to MANY
关系快得多。
我已经注意到表3000
项目中的ONE to MANY
关系,使用LIMIT
加入一个包含30,000
项目的表可以轻松占用11-15秒。 但同样的查询,重新设计与所有ONE TO ONE
关系将花费不到1秒。
所以我的建议是加快你的查询速度。 根据左外连接(desc), “LEFT JOIN和LEFT OUTER JOIN是相同的”所以你使用哪一个并不重要。
但理想情况下,应该使用INNER
因为在你的问题中你说过B.Date1 IS NOT NULL
基于连接选择(desc)中的此父列 ,可以在JOIN中的SELECT中使用父列。
SELECT a.Id FROM A a
INNER JOIN (SELECT b.Id AS 'Id', COUNT(1) as `TotalLinks` FROM B b WHERE ((b.Date1 IS NOT NULL) AND ((a.Date >= b.Date2) AND (a.Date < b.Date1)) GROUP BY b.Id) AS `ab` ON (a.Id = ab.Id) AND (a.Flag = 'Y')
WHERE a.Flag = 'Y' AND b.totalLinks > 0
LIMIT 0, 500
尝试并LIMIT
您想要的数据; 这将减少SQL所需的过滤。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.