以下查询需要执行FOREVER(在Macbook上使用4gig ram时超过30小时) - 我正在寻找使其更有效运行的方法。任何想法都表示赞赏!
CREATE TABLE fc AS
SELECT threadid,
title,
body,
date,
userlogin
FROM f
WHERE pid
NOT IN (SELECT pid FROM ft) ORDER BY date;
(表“f”为~1 Gig / 1,843,000行,表“ft”为168mb,216,000行))
答案 0 :(得分:5)
尝试外连接(我认为MySQL现在支持它们)而不是不在:
create table fc as
select f.threadid
, f.title
, f.body
, f.date
, f.userlogin
from f
left outer join ft
on f.pid = ft.pid
where ft.pid is null
order by date
答案 1 :(得分:2)
从EXPLAIN PLAN开始,查看优化程序的用途。然后在进行更改时重新运行它以查看它们是否有用。
我敢打赌,正确的查询将在几分钟内完成。
答案 2 :(得分:1)
在fc和ft表上的pid上添加聚簇索引。
答案 3 :(得分:0)
确保你在ft上有一个pid索引。听起来你正在获得完整的交叉产品,而不是索引的连接。
答案 4 :(得分:0)
可能会有一些隐藏的成本。运行它需要多长时间:
SELECT count(*)
FROM f
WHERE pid
NOT IN (SELECT pid FROM ft);
如果不花很长时间,那么你的命令的缓慢可能是MySQL在语句执行时复制所有数据,以防它失败并且必须回滚它。 (我在SQL Server上看过这个。)
另外:如果你拿出ORDER BY子句会有什么不同吗?
答案 5 :(得分:0)
f
中有多少行与ft
中的行不匹配?在最极端的情况下,如果pid
中的f
是唯一的,那么您的目标表fc
将包含> 1.6米的行。如果大部分行将以fc
结尾,那么最好分两个阶段执行此操作:
CREATE TABLE fc AS
SELECT threadid,
title,
body,
date,
userlogin
FROM f
ORDER BY date;
DELETE FROM fc
WHERE pid
IN (SELECT pid FROM ft);
顺便说一句,你可以放弃ORDER BY子句吗?那种类型可能需要花费很多周期,这取决于目标表中有多少行。
要考虑的另一件事是EXISTS条款......
CREATE TABLE fc AS
SELECT threadid,
title,
body,
date,
userlogin
FROM f
WHERE NOT EXISTS
(SELECT pid FROM ft
WHERE ft.pid = f.id)
ORDER BY date;
......或者我的两步版......
DELETE FROM fc
WHERE EXISTS
(SELECT pid FROM ft
WHERE ft.pid = f.id);
当子查询生成大量行时,EXISTS可以比IN快很多。然而,正如调整一样,基准测试是关键。