我有两个表包含现有文件名和下载文件名。现有文件表上的61k +记录和下载文件表上的34k +记录。我正在使用此查询来查找尚未下载的文件名!
SELECT * FROM
files
WHEREfilename
<> ''和filename
不在 (SELECTfilename
FROMdownloads
)
当记录很少但现在不能正常工作,几天前,当有50k和20k记录时,这种情况正常,但是在5/6分钟内获得结果变慢,但现在它显示了这个错误:
内部服务器错误500
子进程(php)没有响应退出信号:0
filename字段是表的文件名字段(varchar 255),并且这两个字段都被编入索引。任何帮助PLZ?
答案 0 :(得分:1)
首先,在files
和downloads
上添加索引。这将使搜索速度更快。这可能需要几分钟时间。
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 :(得分:0)
left_join 2表会更好,因此,我们从files表中获取所有记录,并从下载中添加适当的记录。来自下载的空对象文件的文件名是我们需要的文件名,因此,我们过滤只获得这些文件名。
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 :(得分: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正在做什么。