SQL 左连接。花费太长时间。

Ole*_*ner 1 mysql sql join primary-key left-join

好的,这是我的表模式。
我有2张桌子。说表A和表B。表A的主键是PriKeyA bigint(50),表B的主键是PriKeyB varchar(255)。PriKeyA 和 PriKeyB 都包含相同类型的数据。
这个问题需要的表A的相关字段是Last_login_date_in_A(日期),表B是主键本身。
我需要做的是,在 A 中获取那些在表 B 的 PriKeyB 列中不存在的 PriKeyA,并且 Last_login_date_in_A 列应该从当前日期起超过 30 天。基本上我需要表 A 和表 B 的差异以及某个条件(这是这个问题中的日期)
这是我的 SQL 命令

: SELECT A.PriKeyA from A  
 LEFT JOIN B ON A.PriKeyA = B.PriKeyB   
 WHERE B.PriKeyB IS NULL and DATEDIFF(CURRENTDATE,Last_login_date_in_A)>30;
Run Code Online (Sandbox Code Playgroud)

但是,当我运行这个 MySQL 命令时,它需要花费很长的时间(大约 3 小时)。表 A 的大小为 2,50,000,表 B 的大小分别为 42,000 条记录。我认为这个问题可能是因为 PriKeyA 和 PriKeyB 是不同的数据类型。所以我也在CAST(PriKeyB as unsigned)查询中使用了。但这也不起作用。性能略有提高。

可能的问题是什么?我以前使用过左连接,他们从来没有用过这么长时间。

小智 5

查询的费用似乎是出于以下原因:

  • A 的 PK 和 B 的 PK 的 SQL 数据类型不同。
  • 表 A 可能在 Last_login_date_in_A 上没有索引

这意味着必须一次检查表 A 中的所有行,以确定 > 30 天前条件是否为真。如果 A 有 2,500,000 行(正如您在 A 的行数中放置逗号的方式所证明的那样)而不是 250,000 行,则尤其如此。

在 Last_login_date_in_A 上添加索引可能会对您有所帮助,但由于需要更新附加索引,也会稍微减慢表的插入/更新/删除语句时间。

此外,您应该利用文档来解释 MySQL 为您的查询实际选择的查询计划:MySQL 查询计划文档