【发布时间】:2013-07-26 14:25:24
【问题描述】:
好的,这是我的表模式。
我有 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;
但是,当我运行这个 MySQL 命令时,它需要非常长的时间(大约 3 小时)。表 A 的大小为 2,50,000,表 B 的大小分别为 42,000 条记录。我认为由于 PriKeyA 和 PriKeyB 是不同的数据类型,可能会出现此问题。所以我也在查询中使用了CAST(PriKeyB as unsigned)。但这也没有用。性能略有改善。
可能会出现什么问题?我以前用过左连接,他们从来没有用过这么长时间。
【问题讨论】:
-
我怀疑问题出在数据类型上,特别是在查询期间对每一行执行转换。
-
但是类型转换不应该解决这个问题吗?
-
您的数据库在硬件上运行。那里没有神奇的独角兽,如果你至少不使用 InnoDB 并且如果你不优化 MySQL 的设置,那么你就找错了树。此外,当您想知道为什么某件事需要太长时间时,请始终使用
EXPLAIN,并且 MySQL 会告诉您它认为应该做什么,同时推断您要求的数据。 -
@OleGooner 每次比较都会进行转换/转换,有 2500000*42000 次比较(减去优化器可以通过其他条件削减的比较),会有一些转换......
-
您可以创建一个临时表,并提前完成转换,您可以在该表上执行连接,因为较小的表只会导致 47k 强制转换。遗憾的是,索引计算列在 MySQL 上不起作用:-/
标签: mysql sql join left-join primary-key