查询性能-提取未从行中提取子文件的行

时间:2019-06-18 05:07:17

标签: sql sql-server

我正在创建一个基于Web的文件浏览器,文件和文件夹的详细信息存储在数据库中,并与Active Directory用户或组共享。当我必须将网格与共享文件绑定时,如果文件更多,则会花费很多时间,因为我先获取所有文件,然后删除子文件/子目录行。如何忽略子文件/子目录,以提高性能?

这是用户有权访问的文件的示例表。

id |    path                                  |    name         |    parent                      |    isdirectory
-----------------------------------------------------------------------------------------------------------------
1  |    /data/user1/folder1                   |    folder1      |    /data/user1                 |    true
2  |    /data/user1/folder1/text1.txt         |    text1.txt    |    /data/user1/folder1         |    false
3  |    /data/user1/folder1/folder2           |    folder2      |    /data/user1/folder1         |    true
4  |    /data/user1/folder1/folder2/text2.txt |    text2.txt    |    /data/user1/folder1/folder2 |    false
5  |    /data/user2/paper.pdf                 |    paper.pdf    |    /data/user2                 |    false
5  |    /data2/backup/reports                 |    reports      |    /data2/backup               |    true
6  |    /data2/backup/reports/rep1.pdf        |    rep1.pdf     |    /data2/backup/reports       |    false
7  |    /softwaredump                         |    softwaredump |    /                           |    true
8  |    /softwaredump/win10.iso               |    win10.iso    |    /softwaredump               |    false

现在您可以看到该表中有子文件和文件夹。因此,在绑定网格时,我使用此查询

WITH finally AS
    (SELECT DISTINCT
        Parent
        FROM
        files m1
    WHERE Parent NOT IN (
        SELECT Path FROM files WHERE Path LIKE CONCAT(@Path,'/%')
        )
    )
SELECT *
FROM files fin
    INNER JOIN finally ON finally.Parent = fin.Parent
    WHERE fin.Path LIKE CONCAT(@Path,'/%')

此处@Path是用于浏览路径的SP参数,默认值为'',然后再说'/data/user1/folder1'来浏览该文件夹

我得到的预期输出。

id |    path                                  |    name         |    parent                      |    isdirectory
-----------------------------------------------------------------------------------------------------------------
1  |    /data/user1/folder1                   |    folder1      |    /data/user1                 |    true
5  |    /data/user2/paper.pdf                 |    paper.pdf    |    /data/user2                 |    false
5  |    /data2/backup/reports                 |    reports      |    /data2/backup               |    true
7  |    /softwaredump                         |    softwaredump |    /                           |    true

我还添加了非聚集索引。对于大约15000个文件,此查询大约需要20-30秒。

但是,随着文件数量的增加,性能会降低。解决方案是仅选择最顶层,而忽略子文件和子文件夹。但是,共享文件时,它将成为最高级别,并且没有子级别。

这里是一个示例SQLFiddle

0 个答案:

没有答案