Производительность запроса - выборка строк, из которых не извлекаются субфайлы. - PullRequest
2 голосов
/ 18 июня 2019

Я создаю веб-обозреватель файлов, в котором сведения о файлах и папках хранятся в базе данных и предоставляются пользователям или группам 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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...