好的,这是我的表架构。
我有 2 张 table 。说表A和表B。表A的主键是PriKeyA bigint(50),表B的主键是PriKeyB varchar(255)。 PriKeyA 和 PriKeyB 包含相同类型的数据。
本题需要的A表相关字段是Last_login_date_in_A(日期),B表本身就是主键。
我需要做的是,获取表 B 的 PriKeyB 列中不存在的 A 中的那些 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;
然而,当我运行这个 MySQL 命令时,它花费了非常长的时间(大约 3 小时)。表 A 的大小为 2,50,000,表 B 的大小分别为 42,000 条记录。我认为这个问题可能是由于 PriKeyA 和 PriKeyB 是不同的数据类型而引起的。所以我还在查询中使用了 CAST(PriKeyB as unsigned)
。但这也没有用。性能略有提高。
可能会出现什么问题?我以前使用过左连接,但从来没有用过这么长时间。
最佳答案
查询的开销似乎是由于这些原因:
- A 的主键和 B 的主键的 SQL 数据类型不同。
- 表 A 可能没有关于 Last_login_date_in_A 的索引
这意味着必须一次一行地检查表 A 中的所有行,以确定 > 30 天前的条件是否为真。如果 A 有 2,500,000 行(如您在 A 的行数中放置逗号的方式所证明)而不是 250,000,则尤其如此。
在 Last_login_date_in_A 上添加索引可能对您有所帮助,但由于需要更新附加索引,也会稍微减慢表的插入/更新/删除语句时间。
此外,您应该使用文档来解释 MySQL 为您的查询实际选择的查询计划:MySQL query plan documentation
关于mysql - SQL 左连接。花费太长时间。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17883981/