cloudreve/Cloudreve

删除文件时的严重性能问题

Closed this issue · 7 comments

Describe the bug
A clear and concise description of what the bug is.

当前的情景是:

我已经配置了postgresql,redis

/Coding目录下有大约20个文件夹,部分子文件夹下文件数较多(如node_modules),Coding文件夹下大约有980000个文件

当我尝试删除/Coding/tmp文件夹的时候,删除时间非常非常久。即使我的tmp中只有10个文件。(耗时超过1分钟)

但是,当我尝试先进入/Coding/C++文件夹中,全选文件夹中的文件,再删除,发现性能恢复到正常水平(用时2秒,删除40多个文件)

我监控删除过程中的数据库页面,发现删除的过程中,数据库非常吃力。

我推测可能是每删除一次文件都执行了一次父文件夹中的查询?我对源代码不太了解,希望有人可以帮我分析是什么原因?

image

image

To Reproduce
Steps to reproduce the behavior:

如上

Expected behavior
A clear and concise description of what you expected to happen.

删除的时间应该与文件数成正比,不受父文件夹下总文件数量影响。

Desktop (please complete the following information):

  • OS: [e.g. iOS] Windows
  • Browser [e.g. chrome, safari] Edge
  • Version [e.g. 22] Docker v.3.8.3

Additional context
Add any other context about the problem here.

DEBUG下的日志:

image

image

image

或许可能就是因为我的文件数量过多了,如果有批量删除,优化数据库操作的删除方式就更好了

删除9000多个文件耗时7分钟以上

cr删除文件在其后端源码中其实是写的没问题,问题是他删除你执行一次相当于执行了一条sql语句而不是删一个文件执行一条。还看不明白?

那我举一个例子你就看懂了,在cloudreve里面你一次性删除一个文件夹(包括一次性按“删除”去删很多个文件)他是只执行一句sql去删除你想删的全部东西,并不是一个文件一个sql语句去删。

一句sql执行多行操作的时间和多个sql执行多行操作的时间完完全全是不一样的,这个你可以自己去试试。

所以最终结论个人认为他的删除逻辑有问题或者需要更好的一种方式去删除。

不过在V4版本预览中你可以看到作者有新增“回收站”一新功能,这说明他优化了v3删除东西过长这一问题,但是具体他怎么优化又优化到什么样我们只能拭目以待....

cr删除文件在其后端源码中其实是写的没问题,问题是他删除你执行一次相当于执行了一条sql语句而不是删一个文件执行一条。还看不明白?

那我举一个例子你就看懂了,在cloudreve里面你一次性删除一个文件夹(包括一次性按“删除”去删很多个文件)他是只执行一句sql去删除你想删的全部东西,并不是一个文件一个sql语句去删。

一句sql执行多行操作的时间和多个sql执行多行操作的时间完完全全是不一样的,这个你可以自己去试试。

所以最终结论个人认为他的删除逻辑有问题或者需要更好的一种方式去删除。

不过在V4版本预览中你可以看到作者有新增“回收站”一新功能,这说明他优化了v3删除东西过长这一问题,但是具体他怎么优化又优化到什么样我们只能拭目以待....

至少耗时的操作应该放在任务队列里面。如果是sqlite,大量文件删除甚至让整个主进程阻塞,页面都无法加载。

cr删除文件在其后端源码中其实是写的没问题,问题是他删除你执行一次相当于执行了一条sql语句而不是删一个文件执行一条。还看不明白?

那我举一个例子你就看懂了,在cloudreve里面你一次性删除一个文件夹(包括一次性按“删除”去删很多个文件)他是只执行一句sql去删除你想删的全部东西,并不是一个文件一个sql语句去删。

一句sql执行多行操作的时间和多个sql执行多行操作的时间完完全全是不一样的,这个你可以自己去试试。

所以最终结论个人认为他的删除逻辑有问题或者需要更好的一种方式去删除。

不过在V4版本预览中你可以看到作者有新增“回收站”一新功能,这说明他优化了v3删除东西过长这一问题,但是具体他怎么优化又优化到什么样我们只能拭目以待....

至少耗时的操作应该放在任务队列里面。如果是sqlite,大量文件删除甚至让整个主进程阻塞,页面都无法加载。

没用,按他后端源码逻辑如果放到队列一样没区别,能解决的办法只能是重新写他那个删除逻辑才有用,上面已经说了(说明你还没搞清楚他删东西有问题原因在哪……),他删除不是一个文件一句删除的SQL语句,而是按一次删除按钮无论删的有多少都是一句SQL语句去操作数据库。

cr删除文件在其后端源码中其实是写的没问题,问题是他删除你执行一次相当于执行了一条sql语句而不是删一个文件执行一条。还看不明白?
那我举一个例子你就看懂了,在cloudreve里面你一次性删除一个文件夹(包括一次性按“删除”去删很多个文件)他是只执行一句sql去删除你想删的全部东西,并不是一个文件一个sql语句去删。
一句sql执行多行操作的时间和多个sql执行多行操作的时间完完全全是不一样的,这个你可以自己去试试。
所以最终结论个人认为他的删除逻辑有问题或者需要更好的一种方式去删除。
不过在V4版本预览中你可以看到作者有新增“回收站”一新功能,这说明他优化了v3删除东西过长这一问题,但是具体他怎么优化又优化到什么样我们只能拭目以待....

至少耗时的操作应该放在任务队列里面。如果是sqlite,大量文件删除甚至让整个主进程阻塞,页面都无法加载。

没用,按他后端源码逻辑如果放到队列一样没区别,能解决的办法只能是重新写他那个删除逻辑才有用,上面已经说了(说明你还没搞清楚他删东西有问题原因在哪……),他删除不是一个文件一句删除的SQL语句,而是按一次删除按钮无论删的有多少都是一句SQL语句去操作数据库。

那其实我debug日志中显示的40~50ms的大量数据库指令是在操作什么