我正在创建一个基于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。