Mysql,过滤掉第二个表中没有记录的文件

时间:2013-07-01 23:33:22

标签: mysql join filter subquery

这是我在这里发表的第一篇文章。 我搜索过几次,找不到完全满足我需要的主题。 英语不是我的主要语言,所以很可能我没有以最佳方式搜索我找到的东西。

我有一个商业软件的数据库。它将有关文件的信息存储在几个不同的表中。 我们希望做的是过滤掉其中一个表中没有记录的所有文件。

示例:

表“文件”包含有关文件的所有信息 表“path”包含有关文件夹或文件路径的所有信息 表“spreadlink”包含有关文件之间链接的所有信息。

我创建了一个有效的查询,但我觉得它很慢,我的问题是它是否有可能在速度方面做得更好?

我想我可以在我的查询中使用left join之类的东西,但我在使用不同的连接方面没有经验。

有关如何加快速度的建议吗?

我到目前为止的查询:

SELECT 
    f.FileID AS 'FileID', 
    CONCAT(p.path, '/', f.unixname) AS 'filepath', 
    k.Field7 as Keywords, 
    k.Field293 as Fakturerat, 
    f.UTF8Name as FileName, 
    FROM_UNIXTIME(f.CreateDate) AS 'CreateDate', 
    FROM_UNIXTIME(f.ModifyDate) AS 'ModifyDate', 
    FROM_UNIXTIME(f.AccessDate) AS 'AccessDate'
FROM 
    file AS f 
    JOIN path AS p ON (f.pathid=p.pathid)
    JOIN keyword1 AS k ON (f.fileid=k.fileid) 
WHERE 
    path LIKE '/My/path/to/folder/structure/%' 
    AND (f.fileid NOT IN (select TargetFileID from spreadlink )) 
    AND (f.fileid NOT IN (select FileID from spreadlink ));
来自f.FileID

p.FileIDTargetFileIDFileIDspreadlink都是fileID:s,用于标识文件或文件夹,并且是所有文件标识符表。

编辑:这就是mysqlslow日志对查询的说法:

Query_time:12.067222 Lock_time:0.000078 Rows_sent:4153 Rows_examined:3628518

编辑:这里是解释我的查询结果

+----+--------------------+------------+----------------+-------------------+-----------------+---------+--------------------+---------+--------------------------+
| id | select_type        | table      | type           | possible_keys     | key             | key_len | ref                | rows    | Extra                    |
+----+--------------------+------------+----------------+-------------------+-----------------+---------+--------------------+---------+--------------------------+
|  1 | PRIMARY            | k          | ALL            | PRIMARY           | NULL            | NULL    | NULL               | 1441716 |                          | 
|  1 | PRIMARY            | f          | eq_ref         | PRIMARY,BY_PATHID | PRIMARY         | 4       | webnative.k.FileID |       1 | Using where              | 
|  1 | PRIMARY            | p          | eq_ref         | PRIMARY,BY_PATH   | PRIMARY         | 4       | webnative.f.PathID |       1 | Using where              | 
|  3 | DEPENDENT SUBQUERY | spreadlink | index_subquery | BY_FILEID         | BY_FILEID       | 8       | func               |      20 | Using index; Using where | 
|  2 | DEPENDENT SUBQUERY | spreadlink | index_subquery | BY_TARGETFILEID   | BY_TARGETFILEID | 8       | func               |      11 | Using index; Using where | 
+----+--------------------+------------+----------------+-------------------+-----------------+---------+--------------------+---------+--------------------------+

我最终找到了原因。 我在路径中有一个“下划线”(_),并且根据mysql这是一个通配符,它​​减慢了很多。在我的下划线符号前放置一个反斜杠()后,查询只需要1秒钟即可完成。

感谢您对此事的帮助。

1 个答案:

答案 0 :(得分:0)

我强烈建议您使用sqlfiddle.com,以便我们都可以尝试您的查询。您的path字段是否有索引?请尝试以下操作并分享您的结果:

SELECT 
    f.FileID AS 'FileID', 
    CONCAT(p.path, '/', f.unixname) AS 'filepath', 
    k.Field7 as Keywords, 
    k.Field293 as Fakturerat, 
    f.UTF8Name as FileName, 
    FROM_UNIXTIME(f.CreateDate) AS 'CreateDate', 
    FROM_UNIXTIME(f.ModifyDate) AS 'ModifyDate', 
    FROM_UNIXTIME(f.AccessDate) AS 'AccessDate'
FROM 
    file f 
    left join path p ON f.pathid = p.pathid
    left join keyword1 k ON f.fileID = k.fileid 
    left join spreadlink s on f.fileID = s.TargetFileID and f.fileID = s.FileID 
WHERE 
    path LIKE '/My/path/to/folder/structure/%' 
    and f.fileid is null