Description
In the PHP file Access.php (in system/ee/ExpressionEngine/Addons/pro/Service/Access/ folder), there is a function called "requiresValidLicense". It is running this query:
SELECT COUNT(DISTINCT(exp_members.member_id)) AS count
FROM exp_members
LEFT JOIN exp_members_roles ON (exp_members.member_id = exp_members_roles.member_id)
LEFT JOIN exp_members_role_groups ON (exp_members.member_id = exp_members_role_groups.member_id)
LEFT JOIN exp_roles_role_groups ON (exp_members_role_groups.group_id = exp_roles_role_groups.group_id)
WHERE exp_members.role_id IN ({$cpRolesList})
OR exp_members_roles.role_id IN ({$cpRolesList})
OR exp_roles_role_groups.role_id IN ({$cpRolesList})
This query may be okay for databases where the exp_members table contains only few thousand rows. For tables that contain larger number, say 250k rows, it becomes a major bottleneck for the database server.
On a moderate to high traffic server (say 20-50 hits per second), this code spawns off numerous queries (probably one per hit on the web server) and the MySQL server takes nearly all of the CPU capacity even on a 16-core or larger server with 32+ GB RAM. Each query takes inordinately long amount of time to complete and identical queries start building up. The MySQL server immediately runs out of max permitted connections (even if that number is 512 or 1024) and the server becomes unresponsive.
Please review this query and make it less CPU intensive so that it takes much less than a millisecond. Once that is done, this query should also be cached and run only once a day and not on every web page request from the internet... it is only checking for license and that can be done once a day or less frequently.
Thanks.