繁体   English   中英

首先快速对大表的SQL查询然后慢

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM