一键导入
doctrine-performance
Optimize Doctrine ORM performance when queries are slow or memory usage spikes so that applications reduce latency and resource consumption.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Optimize Doctrine ORM performance when queries are slow or memory usage spikes so that applications reduce latency and resource consumption.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Generate and maintain type-safe API clients and React Query integrations with @hey-api/openapi-ts and TanStack React Query v5. Use when implementing OpenAPI-driven data layers to standardize generated hooks, cache keys, mutations, hydration, and client configuration.
Create and maintain Drizzle ORM schemas, relations, and migrations for PostgreSQL. Use when implementing or reviewing Drizzle database layers to keep conventions, type safety, and migration hygiene.
Generate consistent PHP unit tests when writing or refactoring test suites, using PHPUnit and Prophecy with typed ObjectProphecy setup fixtures and data-provider coverage for object variants.
Implement tests, evals, and provider comparisons for MCP servers with @mcpjam/sdk when users want to validate MCP tools with real LLMs, benchmark provider accuracy, or write deterministic and statistical checks for MCP server behavior.
| name | doctrine-performance |
| description | Optimize Doctrine ORM performance when queries are slow or memory usage spikes so that applications reduce latency and resource consumption. |
When having to implement complex Doctrine queries or heavy memory consumption operations and loops. When user asks for optimizing code or a feature depending on Doctrine queries. Ask clarifying questions to ensure refactoring match expected result.
Always Use Query Builder or DQL for Complex Queries
// ❌ Bad - Entity loading overhead
$users = $entityManager->getRepository(User::class)->findAll();
foreach ($users as $user) {
echo $user->getEmail();
}
// ✅ Good - Selective field loading
$emails = $entityManager->createQueryBuilder()
->select('u.email')
->from(User::class, 'u')
->getQuery()
->getResult();
Avoid N+1 Queries with Proper Joins
// ❌ Bad - N+1 problem
$posts = $entityManager->getRepository(Post::class)->findAll();
foreach ($posts as $post) {
echo $post->getAuthor()->getName(); // Triggers separate query per post
}
// ✅ Good - Eager loading with join
$posts = $entityManager->createQueryBuilder()
->select('p', 'a')
->from(Post::class, 'p')
->leftJoin('p.author', 'a')
->getQuery()
->getResult();
Use Partial Objects for Large Datasets
// ✅ Load only needed fields
$result = $entityManager->createQueryBuilder()
->select('partial u.{id, email, username}')
->from(User::class, 'u')
->where('u.active = :active')
->setParameter('active', true)
->getQuery()
->getResult();
Batch Processing Pattern
// ✅ Efficient batch processing with memory management
$batchSize = 100;
$i = 0;
$query = $entityManager->createQuery('SELECT u FROM App\Entity\User u');
foreach ($query->toIterable() as $user) {
$user->setProcessed(true);
if (($i % $batchSize) === 0) {
$entityManager->flush();
$entityManager->clear(); // Detach objects from memory
}
$i++;
}
$entityManager->flush(); // Flush remaining entities
$entityManager->clear();
Use Iterate for Large Result Sets
// ✅ Memory-efficient iteration
$query = $entityManager->createQuery('SELECT u FROM App\Entity\User u');
$iterableResult = $query->toIterable();
foreach ($iterableResult as $row) {
$user = $row[0]; // Access the entity
// Process user
$entityManager->detach($user); // Free memory immediately
}
Add Indexes for Frequently Queried Fields
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Index(name: 'idx_user_email', columns: ['email'])]
#[ORM\Index(name: 'idx_user_active_created', columns: ['active', 'created_at'])]
class User
{
#[ORM\Column(type: 'string', unique: true)]
private string $email;
#[ORM\Column(type: 'boolean')]
private bool $active;
#[ORM\Column(type: 'datetime')]
private \DateTimeInterface $createdAt;
}
Composite Indexes for Multi-Column Queries
// ✅ Good - Composite index for common query pattern
#[ORM\Index(name: 'idx_status_priority_created', columns: ['status', 'priority', 'created_at'])]
class Task
{
// Supports queries like:
// WHERE status = ? AND priority = ? ORDER BY created_at
}
Result Cache Configuration
// Cache query results
$query = $entityManager->createQuery('SELECT u FROM App\Entity\User u WHERE u.role = :role')
->setParameter('role', 'admin')
->useResultCache(true, 3600, 'admin_users_cache');
$results = $query->getResult();
Efficient Counting
// ❌ Bad - Loads all entities
$count = count($repository->findAll());
// ✅ Good - Count in database
$count = $entityManager->createQueryBuilder()
->select('COUNT(u.id)')
->from(User::class, 'u')
->getQuery()
->getSingleScalarResult();
Efficient Existence Check
// ❌ Bad - Loads entity
$user = $repository->findOneBy(['email' => $email]);
$exists = $user !== null;
// ✅ Good - Check in database
$exists = $entityManager->createQueryBuilder()
->select('COUNT(u.id)')
->from(User::class, 'u')
->where('u.email = :email')
->setParameter('email', $email)
->getQuery()
->getSingleScalarResult() > 0;
Subquery Optimization
// ✅ Efficient subquery with DQL
$qb = $entityManager->createQueryBuilder();
$subQuery = $qb->select('IDENTITY(o.user)')
->from(Order::class, 'o')
->where('o.total > :minTotal')
->getDQL();
$users = $entityManager->createQueryBuilder()
->select('u')
->from(User::class, 'u')
->where("u.id IN ($subQuery)")
->setParameter('minTotal', 1000)
->getQuery()
->getResult();
// ❌ Bad - Multiple flushes
foreach ($users as $user) {
$user->setActive(true);
$entityManager->flush(); // Very slow!
}
// ✅ Good - Single flush
foreach ($users as $user) {
$user->setActive(true);
}
$entityManager->flush(); // Single transaction
// For very complex queries or bulk operations, use native SQL
$sql = "
UPDATE user
SET active = 1
WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR)
";
$entityManager->getConnection()->executeStatement($sql);
// Remember to clear entity manager to avoid stale data
$entityManager->clear();
Most Common Optimizations:
clear() for large datasetsEXTRA_LAZY for large collections