L'optimisation des performances SQL est un grand défi pour les programmeurs, car nous rencontrons souvent ce problème : lorsque nous développons un projet, nous pensons que l'expérience fonctionnelle de le tester par nous-mêmes est vraiment bonne, mais après le lancement du projet proprement dit, avec l'augmentation massive dans les données, l'expérience client du système est de pire en pire. Bien sûr, en plus du cadre et du code déraisonnable, la raison principale est que SQL n'a pas été optimisé, ce qui a rendu le système de plus en plus lent.
Parce que je travaille dans une petite entreprise, je fais tout. Je pense que parfois il vaut mieux traiter les symptômes que traiter la cause ! Il y a plusieurs problèmes auxquels il faut prêter attention :
1. La conception de la table de base de données doit être raisonnable, en particulier la conception de la clé primaire. Si la quantité de données dans la table est très importante, la conception de la clé primaire ne doit pas être significative, tout comme ROWID, comme le. GUID de SQL Server, UUID d'Hibernate, etc. Bien entendu, certaines tables du dictionnaire de données peuvent être traitées de manière flexible, et il n'est pas nécessaire de considérer qu'elles doivent être des clés primaires physiques. Dans la conception de clés primaires, les clés primaires composites ne sont généralement pas utilisées.
2. Indexation raisonnable. Index est un outil puissant et un bon moyen d'accélérer notre requête de données. Mais n’ajoutez pas tous les champs. Le principe de l'indexation est similaire à la table des matières d'un livre. Si la table des matières de votre livre porte presque toutes le même nom, vous pouvez imaginer ce qui suit : à quelle vitesse pouvez-vous trouver le contenu spécifique en fonction de la table des matières. ? L'index ne doit pas nécessairement être unique, mais il ne doit pas contenir trop d'enregistrements identiques. De plus, si davantage d'index sont ajoutés, l'espace table TEMP augmentera. Lors de l'exportation de la table et de son importation dans une autre base de données, les index réduiront également l'efficacité de l'importation. À ce stade, vous constaterez également que l'espace table UNDOTBS01. est anormalement grande. L’indice est donc une arme à double tranchant et doit être appliqué de manière raisonnable.
3. J'ai vu des articles très professionnels sur l'optimisation SQL sur Internet, mais j'ai l'impression de ne pas avoir pu les utiliser dans mon projet. Au lieu de cela, j'ai continué à expérimenter et à découvrir quelques principes de base au cours du projet. Personnellement, je pense qu'il n'y a qu'un seul principe d'optimisation SQL, qui est de réduire autant que possible la portée des requêtes. Cela améliorera certainement l'efficacité, et Oracle lui-même peut optimiser le SQL que nous écrivons, donc ce que nous devons faire est de le faire. restreindre autant que possible la portée des requêtes.En parlant de cela, je pense que tout le monde pensera certainement que l'indexation est un outil puissant pour améliorer la vitesse des requêtes. En effet, ce n'est qu'un moyen, et cela découle également du principe de réduction de la portée des requêtes. .
La plupart des requêtes SQL à optimiser sont des requêtes de jointure multi-tables, et les jointures multi-tables incluent également des jointures horizontales et verticales. Celles que nous utilisons le plus sont les jointures verticales. La connexion horizontale signifie généralement que les structures de champs de deux tables sont fondamentalement les mêmes et que certains enregistrements de données d'une table doivent être remplacés par certains enregistrements d'une autre table, c'est-à-dire Lignes + Lignes. La connexion verticale signifie que nous prenons certains champs à interroger de la table A et certains champs à interroger de la table B, puis connectons verticalement les tables extraites des tables A et B en utilisant la partie commune, c'est-à-dire Colonnes + Colonnes.
Instruction de jointure horizontale : sélectionnez a.column1,a.column2 dans la tableA et sélectionnez tous b.column1,b.column2 dans la tableB b.
Notez que lors d'une connexion horizontale, le nombre de colonnes doit être le même et les types de données des colonnes de champ correspondantes doivent être les mêmes. En fait, vous pouvez considérer les tables à réunir comme une copie de l'autre, exactement la même. Quelqu'un peut demander si les colonnes que je souhaite fusionner ont des colonnes différentes ou s'il n'y a pas de colonne du tout, vous pouvez utiliser la méthode suivante
sélectionnez d.dname,d.loc from dept1 d union all select '' dname, e.loc from dept e, regardez "'' dname", nous pouvons facilement trouver que vous pouvez trouver un substitut, utilisez plutôt une chaîne vide Là il n'y a pas de champs, ils peuvent donc être fusionnés.
Instruction de jointure verticale : sélectionnez a.column1,a.column2 dans la tableA, une jointure externe complète, sélectionnez b.column3,b.column4 dans la tableB b sur a.aid=b.bid où..., il s'agit d'un format de jointure externe complète. Cette vitesse est en effet très rapide, mais vous n'aimerez peut-être pas la requête, car il y a certaines lignes de résultats que vous ne voudriez peut-être pas voir du tout. Dans des circonstances normales, nous utilisons davantage la jointure externe gauche et la jointure externe droite. La différence entre les deux est que la jointure externe gauche est principalement basée sur le tableau correspondant au champ de jointure à gauche après, et la jointure externe droite est juste en face. Bien sûr, vous pouvez également utiliser la jointure gauche, la jointure droite. Lors de l’utilisation, j’ai quand même constaté que les connexions externes sont relativement plus rapides.
Pour accélérer l’efficacité des requêtes de connexion verticale, la solution consiste à imbriquer les requêtes. Ce qui suit est un exemple réel du projet :
sélectionnez c.customerid,c.receivedmoney,c.tollcollector,c.receiveddate,c.yearmonth,c.receivedlatefee,
c.receivedfee,c.receivedappend,c.jmman,c.jmmoney,c.name,d.chargeint de
(sélectionnez un identifiant client, un argent reçu, un collecteur de péages, une date de réception, un mois d'année, des frais de retard reçus,
a.receivedfee,a.receivedappend,a.jmman,a.jmmoney,b.name de
(sélectionnez rf.customerid,rf.receivedmoney,rf.tollcollector,rf.receiveddate,rf.yearmonth,rf.receivedlatefee,
rf.receivedfee,rf.receivedappend,rf.jmman,rf.jmmoney de sf_receivedfee rf où
rf.electriccompanyid='1000000001' et rf.dealsign=0 et rf.yearmonth in(200811,200901,200903,200804,200805,200806,200807)
et rf.customerid=1000052545) une jointure externe gauche (sélectionnez xe.employeeid,xe.name dans xt_employee xe) b sur a.tollcollector=b.employeeid)
c jointure externe gauche (sélectionnez cp.chargeint,cp.customerid depuis sf_chargeprotocol cp où cp.customerid=1000052545) d
sur c.customerid=d.customerid
Vous pouvez voir que dans cet exemple, nous filtrons d'abord les enregistrements dont nous avons besoin de chaque table en utilisant presque les mêmes conditions, puis fusionnons les enregistrements. En utilisation réelle, j'ai trouvé que cela est près de 60 fois plus rapide qu'une requête de lien direct. Bien qu'il soit laid et difficile à lire, il résout le problème de performances SQL. Le principe qu'il utilise est toujours de restreindre d'abord la portée, puis d'effectuer une requête de connexion. Si nous nous connectons puis filtrons, cela équivaut à fusionner deux tables, puis à récupérer des données en fonction des conditions.