Dans le projet Laravel, à mesure que le trafic augmente, il n'est pas rare que la base de données soit la vitesse de question. Récemment, lorsque j'ai optimisé l'arrière d'une plate-forme immobilière, j'ai rencontré ce problème et en appris quelques leçons.
L'optimisation de la base de données est l'un des domaines clés des applications de développement et de performance élevées. Il peut améliorer la vitesse de récupération des données, raccourcir le temps de réponse et le temps de chargement des pages et réduire la charge du serveur et minimiser le coût.
Le défi de la plateforme immobilière
Imaginez: vous construisez une excellente plate-forme immobilière qui dessert plusieurs villes et est équipée de filtres de recherche avancés. La liste immobilière se charge rapidement, le filtre de recherche répond rapidement et tout semble parfait. Cependant, avec l'expansion de l'échelle d'application et la croissance de la base d'utilisateurs, les demandes qui ont parfaitement fonctionné au cours du processus de développement ont commencé à fonctionner de plus en plus. Cela semble-t-il familier?
C'est exactement ce que notre plate-forme a rencontrée. L'alerte Sentry a une requête de base de données lente dans l'environnement de production, ce qui nous donne un avertissement. La surveillance montre que la requête des résultats de recherche prend plus de 5 secondes pour terminer - c'est loin de l'expérience rapide que nous promettons!
défauts de requête courants (comment éviter)
1. N 1 Question d'enquête: l'ennemi secret de la base de données
Vous souvenez-vous lorsque vous jouez au jeu, vaincra-t-il un ennemi produit plusieurs ennemis plus petits? C'est essentiellement la même chose que le problème de requête N 1 à Laravel. Vous obtenez la liste des biens immobiliers, puis faites des demandes supplémentaires pour chaque propriété pour obtenir des données connexes. Avant de vous rendre compte, votre base de données traite des centaines de demandes de renseignements, pas seulement une seule.
Ce qui suit est son expression typique:
<code>// 优化前
$properties = Property::all();
foreach ($properties as $property) {
echo $property->agent->name; // 每个房产都会触发一个新的查询
}
// 优化后
// 使用 `with()` 进行预加载
$properties = Property::with(['agent'])->get();
foreach ($properties as $property) {
echo $property->agent->name; // 不需要额外的查询!
}</code>
Copier après la connexion
Copier après la connexion
2. L'art de l'index de la base de données
Il peut comparer l'index de la base de données à l'index de l'écriture - ils peuvent vous aider à trouver ce que vous voulez sans scanner chaque page. Cependant, l'index n'est pas seulement ajouté à chaque colonne. Explorons-nous.
Comprendre différents types d'index
<code>// 基本的单列索引
Schema::table('properties', function (Blueprint $table) {
$table->index('price');
});
// 多列的组合索引
Schema::table('properties', function (Blueprint $table) {
$table->index(['city', 'price']); // 顺序很重要!
});
// 唯一索引
Schema::table('properties', function (Blueprint $table) {
$table->unique('property_code');
});</code>
Copier après la connexion
Copier après la connexion
La meilleure pratique de la stratégie d'index
La séquence des colonnes dans l'indice de combinaison est importante -
<code> // 良好:匹配查询模式
$properties = Property::where('city', 'New York')
->whereBetween('price', [200000, 500000])
->get();
// 索引应匹配此模式
$table->index(['city', 'price']); // 首先是城市,然后是价格</code>
Copier après la connexion
Copier après la connexion
Index sélectif -
Toutes les colonnes ne nécessitent pas d'index. La sélection de certaines colonnes pour indexer certaines colonnes incluent:
les colonnes souvent utilisées dans la clause où et la déclaration par déclaration
Index Colonne de clé extérieure -
N'indemblez pas les colonnes avec une faible sélectivité (comme le logo booléen) -
-
L'utilisation de l'index de surveillance -
3. Choisissez le contenu dont vous avez besoin, pas tout le contenu
L'une des erreurs les plus courantes que j'ai jamais vues (et offertes) est d'utiliser SELECT * par défaut. C'est comme aller à une épicerie, mais acheter des choses dans l'ensemble du magasin, et vous n'avez besoin que d'ingrédients de repas. Ce qui suit est une meilleure façon:
<code> -- 检查索引使用情况的 MySQL 查询
SELECT
table_name,
index_name,
index_type,
stat_name,
stat_value
FROM mysql.index_statistics
WHERE table_name = 'properties';</code>
Copier après la connexion
<code>// 优化前
$properties = Property::all();
foreach ($properties as $property) {
echo $property->agent->name; // 每个房产都会触发一个新的查询
}
// 优化后
// 使用 `with()` 进行预加载
$properties = Property::with(['agent'])->get();
foreach ($properties as $property) {
echo $property->agent->name; // 不需要额外的查询!
}</code>
Copier après la connexion
Copier après la connexion
4. Pour la segmentation du grand ensemble de données
Lors du traitement de grands ensembles de données, gérez tous les contenus en une seule opération qui peuvent submerger les ressources du système et provoquer des goulots d'étranglement. Au lieu de cela, vous pouvez utiliser la méthode Chunk de Laravel pour gérer les enregistrements de traitement par lots enregistrables:
<code>// 基本的单列索引
Schema::table('properties', function (Blueprint $table) {
$table->index('price');
});
// 多列的组合索引
Schema::table('properties', function (Blueprint $table) {
$table->index(['city', 'price']); // 顺序很重要!
});
// 唯一索引
Schema::table('properties', function (Blueprint $table) {
$table->unique('property_code');
});</code>
Copier après la connexion
Copier après la connexion
5. Stratégie de cache efficace et efficace
Les caches sont comme un bon assistant qui peut se souvenir de tout. Cependant, comme tout assistant, il a besoin d'instructions claires.
<code> // 良好:匹配查询模式
$properties = Property::where('city', 'New York')
->whereBetween('price', [200000, 500000])
->get();
// 索引应匹配此模式
$table->index(['city', 'price']); // 首先是城市,然后是价格</code>
Copier après la connexion
Copier après la connexion
Conseils professionnels: ne cachez pas tout! Concentrez-vous sur:
les données qui sont fréquemment accessibles -
Calculez les données avec un coût élevé -
Les données qui ne sont pas changées fréquemment -
Best Practice
Surveillez d'abord, puis optimisez -
Ne vous lancez pas dans le piège de l'optimisation prématurée. Utilisez des outils tels que les journaux de requête ou le télescope construits de Laravel pour identifier le goulot d'étranglement réel.
Penser avec la rassemblement au lieu du cycle
Chaque fois que vous constatez que vous avez écrit une boucle FOREAK qui interroge la base de données, veuillez prendre du recul et demander si vous pouvez utiliser une seule requête pour y faire face. -
appeler stratégiquement
Tout ne doit pas être mis en cache. Faites attention aux requêtes fréquemment accès et à coût élevé.
- Créez l'index
Combattre l'index en tant que répertoire du livre - Vous avez besoin de suffisamment de détails pour trouver rapidement des choses, mais pas trop et le répertoire est plus long que le livre lui-même.
- Défauts communs qui doivent être évités
Ne pas "Pré-charge" la relation inutile
Évitez d'exécuter la requête dans le cycle (piège du problème n 1 pour le camouflage)
Ne cache pas tout - parfois les frais généraux de la gestion du cache dépassent les avantages -
Lorsque vous utilisez l'ordre pour les colonnes non indexes de grands ensembles de données, soyez prudent -
Ne créez pas d'index pour des colonnes rarement utilisées dans les clauses -
Éviter les mises à jour fréquentes; chaque mise à jour nécessite l'indexation -
- Conclusion: c'est un voyage, pas la destination
- L'optimisation de la base de données n'est pas une tâche à un temps qui peut être sélectionnée dans la liste. C'est plus comme prendre soin du jardin -
Entretien régulier et attention pour obtenir les meilleurs résultats
. À partir de ces connaissances de base, le suivi des performances de l'application continue d'améliorer votre méthode.
N'oubliez pas que l'objectif n'est pas de réaliser toutes les technologies d'optimisation que vous connaissez. Au lieu de cela, vous devez trouver un point d'équilibre qui convient à vos cas d'utilisation spécifiques entre Maintenance de code et performances
. Parfois, une simple instruction de pré-charge est plus utile que de passer quelques heures pour effectuer des stratégies d'optimisation complexes.
Qu'est-ce que vous avez rencontré dans le projet Laravel et quels problèmes avez-vous rencontrés dans le projet Laravel? Discutons dans les commentaires!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!