Given documents of the following shapes:
{
"type": "user",
"firstName": "Fred",
"middleName": null,
"lastName": "Smith",
"agencies": ["agency1", "agency2"],
"userType": "cc",
"isLocked": false,
"isEnabled": true,
"role": "mainrole"
}
{
"type": "role",
"code": "mainrole",
"permissions": ["qa|m", "users|m", "roles|e"]
}
The following query:
SELECT META().id AS metaid,
REPLACE(CONCAT2(' ', COALESCE(firstName, ''), COALESCE(middleName, ''), COALESCE(lastName, '')), ' ', ' ') AS name
FROM dev
WHERE type='user'
AND dev.userType <> 'mobile'
AND dev.isEnabled = TRUE
AND dev.isLocked <> TRUE
-- this subquery increases query time by a factor of 10
AND EXISTS(
SELECT NULL
FROM dev b2
WHERE b2.type='role'
AND b2.code = dev.`role`
AND ANY p IN b2.permissions SATISFIES p IN ['qa|m'] END)
AND (dev.agencies IS NULL OR (ANY a IN dev.agencies SATISFIES a = 'agency|myems' END)
)
ORDER BY lastName
Takes ~1.8 seconds to execute, even with what the console suggests is an adequate index.
Advisor shows:
Index Currently Used
CREATE INDEX adv_userType_isLocked_DISTINCT_agencies_agencies_isEnabled_type ON `dev`(`userType`,`isLocked`,(distinct (array `a` for `a` in `agencies` end)),`agencies`) WHERE ((`type` = 'user') and (`isEnabled` = true))
Existing indexes are sufficient.
The problem is that the performance of this query is quite unacceptable, given the extremely low record counts. We have only about 2700 users
, 5 roles
, 40 permissions
and 2 agencies
.
So Iām at a bit of an impasse here. With no ability to provide a ābetterā index, this very basic query is performing miserably, with seemingly no way to improve.
FYI - completely removing the dependent subquery improves performance to around 215ms to execute - still slow, but obviously worlds better. But of course, I need the subquery.
I expect thereās some secret optimization that I can perform and that the index advisor is simply failing to suggest it. But if this is true, then Iām forced to question the usefulness of the advisor.
Help!