1

好的,这是我的表模式。
我有 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)查询中使用了。但这也没有用。性能略有改善。

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

4

1 回答 1

5

The expense of the query appears to be for these reasons:

  • The SQL datatype for A's PK and B's PK aren't the same.
  • Table A probably doesn't have an index on Last_login_date_in_A

What this means is that ALL rows in table A MUST be examined one row at a time in order to determine if the > 30 days ago criteria is true. This is especially true if A has 2,500,000 rows (as evidenced by how you placed your commas in A's row count) instead of 250,000.

Adding an index on Last_login_date_in_A might help you out here, but will also slightly slow down insert/update/delete statement times for the table due to needing to update the additional index.

Additionally, you should utilize the documentation for explaining MySQL's actual chosen query plan for your query at: MySQL query plan documentation

于 2013-07-26T14:42:54.487 回答