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

[Improvement] Refactor query for performance gain #748

Closed
wants to merge 2 commits into from

Conversation

mattamon
Copy link
Contributor

@mattamon mattamon commented Nov 14, 2024

Resolves #700 - at least it is a start.

Refactoring the query is one part.
We should also introduce an index like the following, but we can do this in the core itself with a migration.
See pimcore/pimcore#17834

CREATE INDEX idx_users_workspaces ON users_workspaces_object (userId, cpath, list);
CREATE INDEX idx_users_workspaces ON users_workspaces_asset (userId, cpath, list);

@fashxp
Copy link
Member

fashxp commented Nov 14, 2024

Sadly, this query does not deliver the correct results 😞.

Take the following permission configuration which must not show /Product Data/Accessories/rims:
image

The old query looks something like this for userid 20

SELECT id, path, `key` FROM objects WHERE path = '/Product Data/Accessories/' AND `key` = 'rims' AND
((select list from users_workspaces_object where userId in (20) and LOCATE(CONCAT("/Product Data/Accessories/","rims"),cpath)=1
    ORDER BY LENGTH(cpath) DESC LIMIT 1)=1
OR
(select list from users_workspaces_object where userId in (20) and LOCATE(cpath,CONCAT("/Product Data/Accessories/","rims"))=1
    ORDER BY LENGTH(cpath) DESC LIMIT 1)=1
); 

... and returns zero results - which is correct.

The new query looks something like this

SELECT id, path, `key` FROM objects WHERE path = '/Product Data/Accessories/' AND `key` = 'rims' AND
    EXISTS (
        SELECT 1
        FROM users_workspaces_object
        WHERE userId IN (20)
          AND (
            LOCATE(CONCAT("/Product Data/Accessories/","rims"), cpath) = 1
                OR LOCATE(cpath, CONCAT("/Product Data/Accessories/","rims")) = 1
            )
          AND list = 1
    );

... and returns results - which is wrong.

The reason why while testing in the UI it doesn't show a result is that line - which double checks permissions with calling isAllowed for each element.

This in turns becomes a problem for example with following permission configuration, which should show one line in the grid:
image

With the old query, it works as expected.
With the new query it doesn't - because the query delivers a whole page of false-positives (which are filtered out) so the true-positive doesn't make it into the result.

@mattamon
Copy link
Contributor Author

Sadly, this query does not deliver the correct results 😞.

Take the following permission configuration which must not show /Product Data/Accessories/rims: image

The old query looks something like this for userid 20

SELECT id, path, `key` FROM objects WHERE path = '/Product Data/Accessories/' AND `key` = 'rims' AND
((select list from users_workspaces_object where userId in (20) and LOCATE(CONCAT("/Product Data/Accessories/","rims"),cpath)=1
    ORDER BY LENGTH(cpath) DESC LIMIT 1)=1
OR
(select list from users_workspaces_object where userId in (20) and LOCATE(cpath,CONCAT("/Product Data/Accessories/","rims"))=1
    ORDER BY LENGTH(cpath) DESC LIMIT 1)=1
); 

... and returns zero results - which is correct.

The new query looks something like this

SELECT id, path, `key` FROM objects WHERE path = '/Product Data/Accessories/' AND `key` = 'rims' AND
    EXISTS (
        SELECT 1
        FROM users_workspaces_object
        WHERE userId IN (20)
          AND (
            LOCATE(CONCAT("/Product Data/Accessories/","rims"), cpath) = 1
                OR LOCATE(cpath, CONCAT("/Product Data/Accessories/","rims")) = 1
            )
          AND list = 1
    );

... and returns results - which is wrong.

The reason why while testing in the UI it doesn't show a result is that line - which double checks permissions with calling isAllowed for each element.

This in turns becomes a problem for example with following permission configuration, which should show one line in the grid: image

With the old query, it works as expected. With the new query it doesn't - because the query delivers a whole page of false-positives (which are filtered out) so the true-positive doesn't make it into the result.

Valid points. I used now only some micro-optimization since LIKE seems to performe better than Locate.

At least the results look now better to me but I am not sure what big of an impact it has.
For my tests we are not far off the admin time.

@fashxp fashxp marked this pull request as draft November 25, 2024 07:48
@robertSt7 robertSt7 changed the base branch from 1.6 to 1.7 December 9, 2024 13:52
@cancan101
Copy link
Contributor

@mattamon @kingjia90 was pimcore/pimcore#17834 ever re-PRed against a feature branch?

@mattamon
Copy link
Contributor Author

mattamon commented Dec 12, 2024

@cancan101 yes :) pimcore/pimcore#17847

@mattamon mattamon closed this Dec 12, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Dec 12, 2024
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.

4 participants