Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize PROPFIND having CommentsApp enabled by default #27339

Merged
merged 1 commit into from
Mar 22, 2017

Conversation

mrow4a
Copy link
Contributor

@mrow4a mrow4a commented Mar 8, 2017

The idea here is to reduce number of O(n) queries coming from each PROPFIND in the web browser for instance with enabled comments app (this is by default).

Prefetching required data in one query instead of iterative queries should reduce number of queries to O(1), where N is number of files in the folder.

Query
SELECT object_id, COUNT(object_id) FROM oc_comments C WHERE object_id IN(?) AND object_id NOT IN(SELECT object_id FROM oc_comments_read_markers CRM WHERE C.object_id = CRM.object_id AND CRM.user_id = '?' AND CRM.marker_datetime > C.creation_timestamp) GROUP BY object_id;
does the job very well. Yes, I know it is more OLAP query, but this is what Web Front End is about. This is also most optimal query in our case https://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join

  • Finish first optimization
  • Add chunking of IN() query for more NodeIDs to 100
  • Add unit tests for optimization
  • Inform that Comments app is now "usable" for bigger instances @felixboehm @cdamken

Case 1
selection_051

- 16 queries - this is worst case because caching of getDirectoryListing is not yet done
selection_050

Case 2
100 NON-SHARED/SHARED files, just someone uploaded >100 files to the folder

- 200 queries - this is best case
selection_057
selection_056

@mention-bot
Copy link

@mrow4a, thanks for your PR! By analyzing the history of the files in this pull request, we identified @DeepDiver1975, @PVince81 and @tcitworld to be potential reviewers.

@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 8, 2017

EDIT: Updated in main post

$this->numberOfCommentsForNodes[$folderNodeID] = 0;

// Get IDs for all children of the parent folder
$children = $folderNode->getDirectoryListing();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gets exactly the same result as https://github.com/owncloud/core/blob/master/apps/dav/lib/Connector/Sabre/SharesPlugin.php#L157, so need to be cached, otherwise it is huge overhead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrow4a mrow4a force-pushed the comm_optimize_propfind branch 2 times, most recently from e5946ba to 4e4e05e Compare March 10, 2017 12:58
@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 10, 2017

@DeepDiver1975 @PVince81 New Benchmark in the top post.. Seems comments app will be fixed now. However I want to continue with caching.. I cannot stand it like that :>

* AND CRM.marker_datetime > C.creation_timestamp)
* GROUP BY C.object_id;
*
* @param $objectType string the object type, e.g. 'files'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be

@param string $objectType the object type, e.g. 'files'

* GROUP BY C.object_id;
*
* @param $objectType string the object type, e.g. 'files'
* @param int[] NodeIDs that may be returned
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

phpdoc

@@ -293,6 +303,62 @@ public function testGetNumberOfCommentsForObject() {
$this->assertSame($amount, 4);
}

public function testGetNumberOfUnreadCommentsForNodes() {
$manager = $this->getManager();
$user1 = $this->createMock('\OCP\IUser');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better use

IUser::class

@mrow4a mrow4a force-pushed the comm_optimize_propfind branch 2 times, most recently from 76d2686 to 4e84cd2 Compare March 10, 2017 23:35
@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 12, 2017

@butonic Jorn, do you know which part of the querybuilder for ORACLE could cause error below in

public function getNumberOfUnreadCommentsForNodes($objectType, $objectIds, IUser $user) {
? For other DBMS it is ok

selection_059

I have problems spotting an issue, @DeepDiver1975 says it is the c and crm is not escaped, but not sure how to address that.

@butonic
Copy link
Member

butonic commented Mar 12, 2017

It seens object_id is not always escaped.

@butonic
Copy link
Member

butonic commented Mar 12, 2017

Try using an alias for c.object_id. Especially in The count function.

@mrow4a mrow4a force-pushed the comm_optimize_propfind branch 2 times, most recently from 9488209 to 53bbd3e Compare March 12, 2017 12:00
@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 12, 2017

@PVince81 @DeepDiver1975 Covered will unit tests and checked manually. To review

@butonic
Copy link
Member

butonic commented Mar 12, 2017

C and CRM are not a problem, as long as they are consistently escaped or not escaped. In contrast to mysql, postgres or sqlite oracle uppercases unquoted identifiers.

$objectIdChunks = array_chunk($objectIds, 100);
foreach ($objectIdChunks as $objectIdChunk) {
// Fetch only records from oc_comments which are in specified int[] NodeIDs array and satisfy specified $objectType
$qbMain->selectAlias('object_id', 'id')->selectAlias($qbMain->createFunction('COUNT(object_id)'), 'count')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

>createFunction('COUNT(id)'), you created an alias. try using it in the count

@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 12, 2017

Jenkins error?

selection_061

@butonic
Copy link
Member

butonic commented Mar 12, 2017

The mysql docker seems dead?

@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 13, 2017

@DeepDiver1975 @PVince81 Tests are passing, what do we do with it? Travis?

@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 13, 2017

@DeepDiver1975 @PVince81 This PR is ready from my side. All checks passing.

@mrow4a mrow4a force-pushed the comm_optimize_propfind branch 5 times, most recently from de9fd29 to 260f724 Compare March 14, 2017 14:15
@jvillafanez
Copy link
Member

I haven't tested the code but it looks fine.

@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 14, 2017

Do we have behavioural tests for comments? Better AI test it @jvillafanez @SamuAlfageme @DeepDiver1975

…quired data in one query instead of iterative queries.
@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 20, 2017

@jvillafanez Any new input on this PR? Does CommentsApp have integration tests?

@PVince81
Copy link
Contributor

@mrow4a yes:

± % grep -lrie comment tests/integration 
tests/integration/config/behat.yml
tests/integration/features/bootstrap/CommentsContext.php
tests/integration/features/comments.feature
tests/integration/features/provisioning-v1.feature

@PVince81
Copy link
Contributor

Looks like the comments integration tests are only for the comments Webdav endpoint but not for the files endpoint.

Tests are missing for the property "oc:comments-count", "oc:comments-unread", "oc:comments-href".

@mrow4a please work with @SergioBertolinSG to get some tests for this added.
The tests should have users sharing a file, one user adding a comment and the other user retrieving the above properties on directly that file.
Then do the same with "Depth: 1" on the parent folder to test the pre-fetching code path.

You can run the integration tests with these commands:

% cd tests/integration
% sudo -u wwwrun ./run.sh features/comments.feature

(you can also add line number of the scenario "comments.feature:191".

@SergioBertolinSG
Copy link
Contributor

@PVince81 @mrow4a Ok.

@jvillafanez
Copy link
Member

No more changes from my side.

@PVince81
Copy link
Contributor

@SergioBertolinSG is working on comments tests separately, merging this.

👍

@PVince81 PVince81 merged commit a50acb4 into master Mar 22, 2017
@PVince81 PVince81 deleted the comm_optimize_propfind branch March 22, 2017 10:42
@lock
Copy link

lock bot commented Aug 3, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Aug 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants