mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
feat: db perf improvements
This commit is contained in:
@@ -3468,11 +3468,34 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
$document->setAttribute('$databaseId', $database->getId());
|
||||
$document->setAttribute('$collectionId', $collection->getId());
|
||||
|
||||
static $relatedCollectionsCache = [];
|
||||
|
||||
$relationships = \array_filter(
|
||||
$collection->getAttribute('attributes', []),
|
||||
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
|
||||
);
|
||||
|
||||
// First collect all required related collection IDs
|
||||
$relatedCollectionIds = [];
|
||||
foreach ($relationships as $relationship) {
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$cacheKey = 'database_' . $database->getInternalId() . '_' . $relatedCollectionId;
|
||||
|
||||
if (!isset($relatedCollectionsCache[$cacheKey])) {
|
||||
$relatedCollectionIds[$cacheKey] = $relatedCollectionId;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch all required collections in a single batch if needed
|
||||
if (!empty($relatedCollectionIds)) {
|
||||
foreach ($relatedCollectionIds as $cacheKey => $relatedCollectionId) {
|
||||
$relatedCollectionsCache[$cacheKey] = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Now process each relationship with cached collection data
|
||||
foreach ($relationships as $relationship) {
|
||||
$related = $document->getAttribute($relationship->getAttribute('key'));
|
||||
|
||||
@@ -3491,8 +3514,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
}
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
// todo: Use local cache for this getDocument
|
||||
$relatedCollection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId));
|
||||
$cacheKey = 'database_' . $database->getInternalId() . '_' . $relatedCollectionId;
|
||||
$relatedCollection = $relatedCollectionsCache[$cacheKey];
|
||||
|
||||
foreach ($relations as $index => $doc) {
|
||||
if ($doc instanceof Document) {
|
||||
|
||||
@@ -1915,7 +1915,17 @@ App::post('/v1/functions/:functionId/executions')
|
||||
throw new Exception($validator->getDescription(), 400);
|
||||
}
|
||||
|
||||
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
|
||||
// Cache keys for frequently accessed documents
|
||||
static $functionCache = [];
|
||||
static $deploymentCache = [];
|
||||
static $buildCache = [];
|
||||
|
||||
// Get function document with caching
|
||||
$cacheKey = $functionId;
|
||||
if (!isset($functionCache[$cacheKey])) {
|
||||
$functionCache[$cacheKey] = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
|
||||
}
|
||||
$function = $functionCache[$cacheKey];
|
||||
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
@@ -1934,7 +1944,13 @@ App::post('/v1/functions/:functionId/executions')
|
||||
throw new Exception(Exception::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported');
|
||||
}
|
||||
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', '')));
|
||||
// Get deployment document with caching
|
||||
$deploymentId = $function->getAttribute('deployment', '');
|
||||
$deploymentCacheKey = $deploymentId;
|
||||
if (!isset($deploymentCache[$deploymentCacheKey])) {
|
||||
$deploymentCache[$deploymentCacheKey] = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $deploymentId));
|
||||
}
|
||||
$deployment = $deploymentCache[$deploymentCacheKey];
|
||||
|
||||
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
|
||||
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
|
||||
@@ -1945,7 +1961,12 @@ App::post('/v1/functions/:functionId/executions')
|
||||
}
|
||||
|
||||
/** Check if build has completed */
|
||||
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
|
||||
$buildId = $deployment->getAttribute('buildId', '');
|
||||
$buildCacheKey = $buildId;
|
||||
if (!isset($buildCache[$buildCacheKey])) {
|
||||
$buildCache[$buildCacheKey] = Authorization::skip(fn () => $dbForProject->getDocument('builds', $buildId));
|
||||
}
|
||||
$build = $buildCache[$buildCacheKey];
|
||||
if ($build->isEmpty()) {
|
||||
throw new Exception(Exception::BUILD_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -809,16 +809,38 @@ App::get('/v1/users/:userId/memberships')
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
$memberships = array_map(function ($membership) use ($dbForProject, $user) {
|
||||
$team = $dbForProject->getDocument('teams', $membership->getAttribute('teamId'));
|
||||
|
||||
$memberships = $user->getAttribute('memberships', []);
|
||||
|
||||
// Get all team IDs to fetch in a single query
|
||||
$teamIds = array_map(function ($membership) {
|
||||
return $membership->getAttribute('teamId');
|
||||
}, $memberships);
|
||||
|
||||
// Fetch all teams in a single query if there are any memberships
|
||||
$teams = [];
|
||||
if (!empty($teamIds)) {
|
||||
$teamsDocuments = $dbForProject->find('teams', [
|
||||
Query::equal('$id', $teamIds),
|
||||
]);
|
||||
|
||||
// Index teams by ID for quick lookup
|
||||
foreach ($teamsDocuments as $team) {
|
||||
$teams[$team->getId()] = $team;
|
||||
}
|
||||
}
|
||||
|
||||
// Now map memberships with team data
|
||||
$memberships = array_map(function ($membership) use ($teams, $user) {
|
||||
$teamId = $membership->getAttribute('teamId');
|
||||
$team = $teams[$teamId] ?? null;
|
||||
|
||||
$membership
|
||||
->setAttribute('teamName', $team->getAttribute('name'))
|
||||
->setAttribute('teamName', $team ? $team->getAttribute('name') : '')
|
||||
->setAttribute('userName', $user->getAttribute('name'))
|
||||
->setAttribute('userEmail', $user->getAttribute('email'));
|
||||
|
||||
|
||||
return $membership;
|
||||
}, $user->getAttribute('memberships', []));
|
||||
}, $memberships);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'memberships' => $memberships,
|
||||
|
||||
Reference in New Issue
Block a user