In Drupal 6, the 'Switch User' block contains an auto-populate field search form and also has a few immediate links that one can switch to.
However the query used to generate the list of users one can switch to consistently is at the top of the list of long queries on each page render that contains the block (using devel module's own query logging tools).
The query to get a list of < 10 users one can switch to takes anywhere between 1300 and 1600 milliseconds (thats over 1 second!) to execute!
SELECT DISTINCT u.uid, u.name, u.access FROM users u LEFT JOIN users_roles r ON u.uid = r.uid WHERE (u.uid = 1 OR r.rid IN (3,4)) AND u.status < 0 ORDER BY u.access DESC LIMIT 0, 10
I've found that if you replace the LEFT JOIN with an INNER JOIN the query execution time goes down to 10 milliseconds.
Not sure if this also affects D7 or D8.
Comment | File | Size | Author |
---|---|---|---|
#2 | devel-switch-user-list-perf-2624370-2-D6.patch | 821 bytes | jwilson3 |
Comments
Comment #2
jwilson3This patch for D6 simply swaps LEFT JOIN with INNER JOIN. The result set is exactly the same and the query execution time goes down by a factor of 100.
Comment #3
salvisI see your pain. You seem to have a very large number of users and roles! How many?
The way I read the SQL, going to an inner join will remove user 1 from the result set if s/he does not have any of the listed roles. That's a no-go, of course, and you'll have to look for an alternative solution.
As always, D8 needs to go first.
Comment #4
willzyx CreditAttribution: willzyx commented@salvis I'm not sure if the 8.x branch is affected by this issue.
In 8.x we use entity query for the user list; the query for determine the prioritized users already uses INNER JOIN on roles table:
therefore the query not necessarily include user 1 in the result set if s/he does not have any of the listed roles.
Do we need to open an issue for that?
Comment #5
salvisThanks for checking the D8 query, willzyx!
It makes sense to create a role to display the block, and give it to user 1, too, but I guess you don't necessarily need to do that. So, yes, I think user 1 should be included in the list — s/he can switch away and should always be able to switch back (if the other user has the permission).
Moving this to D7 which does have the outer join, and postponing until we have a full solution for D8.
Comment #6
jwilson3Would adding the USER1 to the list as a special case (after the query) be a feasible solution?
P.S: I have 1260 users on this D6 site.
Comment #7
salvisYes, I think so, at the top, IF s/he's not already in the list, and remove the last one, to keep the count correct.
The list is sorted with the most recently used account at the top (or at least close to that). We'll lose that feature, because we can't tell where user 1 should be inserted, but that's a fair trade-off.
However, after thinking about it some more here's another idea: not adding user 1 could actually be a useful feature! If you don't allow entering any user name, the user can switch only among the listed accounts, and if user 1 didn't have the "switch user" permission, s/he would never be listed.
I'm not sure it's waterproof... Any thoughts?
Comment #8
willzyx CreditAttribution: willzyx commentedClosing for lack of activity. Feel free to reopen if the issue still exists