Analyze query performance using EXPLAIN.
$result = $db->find()
->from('users')
->where('email', 'user@example.com')
->explain();
// Returns execution plan
/*
Array
(
[0] => Array
(
[id] => 1
[select_type] => SIMPLE
[table] => users
[type] => ref
[possible_keys] => email
[key] => email
[key_len] => 203
[ref] => const
[rows] => 1
[Extra] => Using where
)
)
*/$result = $db->find()
->from('users')
->where('email', 'user@example.com')
->explain();
// Returns query plan with nodes// PostgreSQL only
$result = $db->find()
->from('users')
->where('email', 'user@example.com')
->explainAnalyze();
// Returns actual execution timeGet optimization recommendations automatically:
$analysis = $db->find()
->from('users')
->where('status', 'active')
->explainAdvice();
// Returns ExplainAnalysis object with:
// - rawExplain: Original EXPLAIN output
// - plan: Parsed execution plan
// - issues: Detected issues
// - recommendations: Optimization suggestions$analysis = $db->find()
->from('users')
->where('email', 'user@example.com')
->explainAdvice('users');
// Check plan details
echo "Access Type: " . $analysis->plan->accessType . "\n";
echo "Used Index: " . ($analysis->plan->usedIndex ?? 'None') . "\n";
echo "Estimated Rows: " . $analysis->plan->estimatedRows . "\n";
// Check for issues
if (!empty($analysis->plan->tableScans)) {
echo "Full table scans detected: " . implode(', ', $analysis->plan->tableScans) . "\n";
}
// Get recommendations
foreach ($analysis->recommendations as $rec) {
echo "[{$rec->severity}] {$rec->type}: {$rec->message}\n";
if ($rec->suggestion) {
echo " Suggestion: {$rec->suggestion}\n";
}
}$analysis = $db->find()
->from('orders')
->where('status', 'pending')
->explainAdvice();
// Check for full table scans
if (!empty($analysis->plan->tableScans)) {
foreach ($analysis->plan->tableScans as $table) {
echo "Full table scan on: $table\n";
}
}$analysis = $db->find()
->from('users')
->where('email', 'user@example.com')
->explainAdvice('users');
// Recommendations include SQL suggestions
foreach ($analysis->recommendations as $rec) {
if ($rec->type === 'missing_index' && $rec->suggestion) {
// Execute suggestion to create index
// $db->rawQuery($rec->suggestion);
echo $rec->suggestion . "\n";
}
}$analysis = $db->find()
->from('users')
->where('age', 25, '>')
->explainAdvice();
if ($analysis->hasCriticalIssues()) {
echo "⚠ Critical performance issues detected!\n";
}
if ($analysis->hasRecommendations()) {
echo "ℹ Optimization recommendations available\n";
}$columns = $db->find()
->from('users')
->describe();
// Returns column information
/*
Array
(
[0] => Array
(
[Field] => id
[Type] => int(11)
[Null] => NO
[Key] => PRI
[Default] => NULL
[Extra] => auto_increment
)
...
)
*/$indexes = $db->rawQuery('SHOW INDEX FROM users');$result = $db->find()
->from('users')
->where('email', 'user@example.com')
->explain();
if ($result[0]['key'] === null) {
echo "No index used!";
}// Enable query log
$db->enableQueryLog();
$users = $db->find()
->from('users')
->join('profiles', 'profiles.user_id', 'users.id')
->get();
$log = $db->getQueryLog();
foreach ($log as $query) {
echo $query['sql'] . "\n";
echo "Time: " . $query['time'] . "ms\n";
}- Performance - Query optimization
- Common Pitfalls - Mistakes to avoid
- Troubleshooting - Common issues