- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
122 lines
3.8 KiB
PHP
122 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Database\Profiling;
|
|
|
|
/**
|
|
* Query analysis result with optimization suggestions
|
|
*/
|
|
final readonly class QueryAnalysis
|
|
{
|
|
public function __construct(
|
|
public QueryProfile $profile,
|
|
public array $suggestions,
|
|
public array $issues,
|
|
public array $indexRecommendations,
|
|
public ?string $executionPlan,
|
|
public int $optimizationScore
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Get analysis grade based on optimization score
|
|
*/
|
|
public function getAnalysisGrade(): string
|
|
{
|
|
return match (true) {
|
|
$this->optimizationScore >= 90 => 'A',
|
|
$this->optimizationScore >= 80 => 'B',
|
|
$this->optimizationScore >= 70 => 'C',
|
|
$this->optimizationScore >= 60 => 'D',
|
|
default => 'F'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get priority level for optimization
|
|
*/
|
|
public function getOptimizationPriority(): string
|
|
{
|
|
return match (true) {
|
|
$this->optimizationScore < 40 => 'critical',
|
|
$this->optimizationScore < 60 => 'high',
|
|
$this->optimizationScore < 75 => 'medium',
|
|
default => 'low'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Check if query needs immediate attention
|
|
*/
|
|
public function needsImmediateAttention(): bool
|
|
{
|
|
return $this->optimizationScore < 40 ||
|
|
count($this->issues) > 3 ||
|
|
$this->profile->executionTime->toSeconds() > 5.0;
|
|
}
|
|
|
|
/**
|
|
* Get top recommendations (most important)
|
|
*/
|
|
public function getTopRecommendations(int $limit = 3): array
|
|
{
|
|
// Prioritize issues over suggestions
|
|
$recommendations = [];
|
|
|
|
foreach ($this->issues as $issue) {
|
|
$recommendations[] = ['type' => 'issue', 'message' => $issue, 'priority' => 'high'];
|
|
}
|
|
|
|
foreach ($this->indexRecommendations as $recommendation) {
|
|
$recommendations[] = ['type' => 'index', 'message' => $recommendation, 'priority' => 'medium'];
|
|
}
|
|
|
|
foreach ($this->suggestions as $suggestion) {
|
|
$recommendations[] = ['type' => 'suggestion', 'message' => $suggestion, 'priority' => 'low'];
|
|
}
|
|
|
|
return array_slice($recommendations, 0, $limit);
|
|
}
|
|
|
|
/**
|
|
* Convert to array for serialization
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'profile_id' => $this->profile->id,
|
|
'query_type' => $this->profile->getQueryType(),
|
|
'execution_time_ms' => $this->profile->executionTime->toMilliseconds(),
|
|
'optimization_score' => $this->optimizationScore,
|
|
'analysis_grade' => $this->getAnalysisGrade(),
|
|
'optimization_priority' => $this->getOptimizationPriority(),
|
|
'needs_immediate_attention' => $this->needsImmediateAttention(),
|
|
'issues_count' => count($this->issues),
|
|
'suggestions_count' => count($this->suggestions),
|
|
'index_recommendations_count' => count($this->indexRecommendations),
|
|
'issues' => $this->issues,
|
|
'suggestions' => $this->suggestions,
|
|
'index_recommendations' => $this->indexRecommendations,
|
|
'top_recommendations' => $this->getTopRecommendations(),
|
|
'execution_plan' => $this->executionPlan,
|
|
'profile' => $this->profile->toArray(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get formatted summary
|
|
*/
|
|
public function getSummary(): string
|
|
{
|
|
return sprintf(
|
|
"Query Analysis [%s] - Score: %d/100, Issues: %d, Suggestions: %d, Priority: %s",
|
|
$this->getAnalysisGrade(),
|
|
$this->optimizationScore,
|
|
count($this->issues),
|
|
count($this->suggestions),
|
|
ucfirst($this->getOptimizationPriority())
|
|
);
|
|
}
|
|
}
|