2013-06-28 93 views
0

我有两个表包含现有的文件名和下载的文件名。 Theres 61k +记录现有文件表和34k +记录下载文件表。我正在使用此查询来查找尚未下载的文件名!Mysql从大型两个表中找到不匹配的记录

SELECT * FROM files WHERE filename <> '' AND filename NOT IN (SELECT filename FROM downloads)

这是以前工作正常,即使世界上几个记录,但它不是现在的工作,过几天,当有50K和20K的记录,它是越来越慢的像5/6分钟得到结果,但现在它显示这错误:

Internal Server Error 500
No response from subprocess (php) with exit signal: 0

文件名字段是表的文件​​名字段(varchar 255),并且这两个字段都被编入索引。任何帮助PLZ?

+0

这是您要托管的数据库吗? – Brian

回答

0

将left_join添加到2个表会更好,因此,我们从文件表中获取所有记录并从下载中添加适当的记录。来自下载文件的文件名是我们需要的文件名,所以我们过滤掉只有这些文件名。

select f.filename from files as f left join downloads as d on f.filename=d.filename where d.filename is null and f.filename<>'' 

我的实现仅仅是两个简单的扫描:

mysql> explain select f.filename from files as f left join downloads as d on f.filename=d.filename where d.filename is null and f.filename<>''; 
    SIMPLE f Using where; Using index; 
    SIMPLE d Using where; Using index; Not exists 

原始一个使用子查询:

mysql> explain SELECT * FROM files WHERE filename <> '' AND filename NOT IN (SELECT filename FROM downloads); 
    PRIMARY    files 
    DEPENDENT SUBQUERY downloads 
+2

请避免使用代码唯一的答案,并且请包括一些关于为什么您的答案可以解决问题的解释。 – rgettman

0

一种更好的方式来编写查询会是这样(假设你有一个id列):

SELECT a.* 
FROM files a 
LEFT JOIN downloads b ON b.filename = a.filename 
WHERE b.id IS NULL 
AND a.filename != '' 

由于PHP脚本超时,错误可能会回来。如果这个查询的运行速度还不够快,请在开头以EXPLAIN的形式发布上面的查询的输出,这样我们就可以看到MySQL正在做什么。

1

首先,在filesdownloads上加上索引。这会使搜索速度更快。这可能需要几分钟的时间。

ALTER TABLE files ADD INDEX (filename); 
ALTER TABLE downloads ADD INDEX (filename); 

然后,使用LEFT JOIN而不是子查询。

SELECT f.* 
FROM files f 
LEFT JOIN downloads d ON 
    d.filename = f.filename 
WHERE 
    d.filename IS NULL 
    AND f.filename <> '' 

这些更改后,搜索应该不到一秒钟。

+1

在此处进行投票,因为这仅仅是提及索引的答案,这可能是OP问题的根源。 –

+0

不知道为什么,但仍然没有为我工作,我检查了phpmyadmin,约10分钟后,这个查询显示500错误,可能为两个表上的60K +记录? –

相关问题