Question

I got 3 tables:

procedures (some kind of information about different internal procedures)

procedure_department (link table, for which department each procedure is valid for)

permissions (each user can add/edit/delete procedure he got permissions to)

Im willing to select all the procedures that the current user got access to or added himself.

$sql = "SELECT p.id, p.name, p.type, p.status
        FROM procedures AS p
            LEFT JOIN procedure_department AS pd ON p.id = pd.procedureID
        WHERE p.addedBy = 47 OR pd.departmentID IN (SELECT `option` FROM permissions WHERE user = 47 AND module = 'info' AND permission = 'add') ";

However it takes years to execute and I would like to see any suggestions for optimization from structure or query point of view.

Was it helpful?

Solution

Although this has been fixed in more recent versions, some versions of MySQL do a poor job of optimizing in with a subquery. You can replace it with exists:

SELECT p.id, p.name, p.type, p.status
FROM procedures p LEFT JOIN
     procedure_department pd
     ON p.id = pd.procedureID
WHERE p.addedBy = 47 OR
      exists (SELECT 1
              FROM permissions
              WHERE user = 47 AND module = 'info' AND permission = 'add' and
                    option = pd.departmentID
             );

For best performance, add an index on permissions(option, user, module, permission).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top