Amélioration de performances d'une base SQL Server 2000 - SQL/NoSQL - Programmation
Marsh Posté le 26-07-2005 à 18:48:03
Essaie de faire un UPDATE FROM, en faisant une jointure plutôt qu'un curseur sur chaque ligne du fichier puis une requête par numéro de téléphone.
Ca devrait grandement améliorer les résultats
Par contre, là où ça va être chaud, c'est ensuite de retrouver les lignes à flager dans ta table temporaire...
Marsh Posté le 27-07-2005 à 10:03:14
Ok, je te remercie on planche dessus voir si c possible, on risque aussi de faire la même chose pour les INSERT, mais y'a les critères à respecter et voir comment on peut mettre à jour seulement les lignes non insérées, je pense qu'on doit faire la mise à jour avant l'insertion.
Sinon t'entends koi par :
"Par contre, là où ça va être chaud, c'est ensuite de retrouver les lignes à flager dans ta table temporaire..."
Et aussi, comment faire pour nettoyer le log
Merci
Marsh Posté le 27-07-2005 à 10:51:34
Ben c'est justement ce que tu dis : c'est que mettons que t'as un traîtement du genre : (ça ressemble un peu à ce dont tu parles)
J'ai copies les lignes de la table A ayant le flag 0 et qui ne sont pas présentes dans la table B, puis le passe le flag à 1.
Je ne traîte par contre pas les lignes dont le flag est à 1.
=> Résultat, si tu fais le traîtement avant de passer au flag à 1, ben quand tu refais une requête pour trouver lesquelles tu viens de traîter, elles ne répondent plus au critère. Et vice versa, si tu les flag avant, alors elle ne répondent plus au critère de recopie.
J'ai l'impression que ce que tu décris contient ce genre de problématique
Sinon, pour la maintenance des logs, je ne me souviens plus du tout. Normalement, ça se fait via les plans de maintenance de SQL Server, au moment du backup. Par contre, il me semble que l'action "de base" qu'il fait lui ne suffit pas, mais je ne me souviens plus dans le détail
J'ai galéré un coup avec pendant 2 jours, et depuis je ne m'en occupe plus, je délègue
Marsh Posté le 27-07-2005 à 12:03:54
Bon, je regarde ton truc
Alors, j'ai besoin d'explications :
- s'il est présent et coché au rebut (BIT à 1), elle regarde alors si la ville, le code postal et le nom ne sont pas tout à fait ressemblant à ce qui est déjà présent (NOT LIKE), alors elle met à jour et enlève ce prospect des rebuts (BIT à 0), sinon elle met seulement à jour sans décoché le bit ;
J'ai besoin d'explications quant au point en gras, parceque je ne sais pas ce que tu fais comme traîtement. Pour le moment, je fais simplement faire "#tmp.cp like tbl.cp" vu que je ne vois pas ce que tu entends pas des lignes et "vraiment ressemblant"
Sinon, je viens de voir... 1 Go de RAM pour un serveur de base de données... Comment dire... Votre société est vraiment sur la paille ?
Marsh Posté le 27-07-2005 à 12:32:51
C'est pas ça que tu veux en fait ? (en très simple finalement)
Code :
|
(sans le rollback évidement, mais c'est chiant de tout se retaper à chaque fois )
Sortie :
Code :
|
Marsh Posté le 27-07-2005 à 15:28:21
Merci pour ta soluce, on avait pas pensé à la clause OR qui va nous permettre de combiner 3 UPDATE en 1
Après il reste le INSERT, mais s'il est exécuté ensuite les insertion des lignes déjà mises à jour seront impossibles !
Et pour le Go de RAM ben non c juste que c t fourni avec mais surement qu'on augmentera ca si apparement c'est un peu limite
Oki merci
Marsh Posté le 27-07-2005 à 17:41:45
Je viens de découvrir un autre problème :
Après mes UPDATE (qui fonctionnent me semble-t-il), je fais un INSERT INTO... SELECT... pour insérer tous les prospects de la table temporaire qui ne sont pas encore enregistrés.
Mais pour donner un index unique, j'ai placé un trigger sur cette table qui se charge de trouver les emplacements d'id vides.
Mais apparement quand j'exécute ma procédure, le trigger n'est appelé qu'une seule fois alors qu'il faudrait qu'il le soit pour chaque ligne insérée.
Est-ce que c'est possible qu'il y ait un problème à ce niveau et si oui comment le contourner ??
Merci.
Marsh Posté le 27-07-2005 à 18:08:43
Il faut faire un curseur dans ton trigger, qui va parcourir la table "inserted".
A moins que tu puisses t'en tirer avec une jointure entre inserted et une autre table que tu mets à jour.
Marsh Posté le 28-07-2005 à 11:30:57
Bon on part sur la jointure, mais le problème c'est qu'on ne sait pas comment trouver un certain nombre d'index qui ne sont pas utilisés dans la table Prospect.
Y'aurait la soluce de créer une table bidon avec tous les id possible (de 1 à 99 999 999) et de sélectionner dans cette liste, ceux qui ne sont présents ni dans Prospect ni dans la temporaire d'id prévu pour faire la jointure avec Inserted. Mais comment créer cette table bidon sans boucle!!
pour l'instant on arrive à sélectionner seulement les id non utilisés qui sont précédés par un id existant avec ça :
Code :
|
Mais si plusieurs trous se suivent on ne peut pas les trouver comme ça. Alors il faudrait aussi comparer avec les id entrés dans la temporaire. Sauf que :
Code :
|
eh ben c impossible !!
Une solution ??
Marsh Posté le 29-07-2005 à 01:06:41
Je comprends rien à tes explications
Un exemple vaut mieu qu'un long discours :
-> 10 lignes de chaque table en partant du principe que "c'est toute la table"
-> Et le résultat attendu
Si j'ai bien compris, tu veux extraire la liste des ID disponibles dans ta table histoire par exemple de boucher les trous avec les insert futurs c'est ça ?
Marsh Posté le 29-07-2005 à 01:26:24
hmmm... je viens de comprendre ce que tu veux faire...
c'est lors du insert des nouvelles lignes, tu ne veux pas planter si l'id est déjà pris c'est ça ?
pourquoi tu n'utilises pas simplement un auto-incrément ? c'est pas bien gênant si t'as des trous.
Marsh Posté le 29-07-2005 à 01:41:00
En répondant à ce topic :
http://forum.hardware.fr/hardwaref [...] m#t1163021
Je viens d'avoir l'idée du sciècle !
=> Tu passes par un numéro auto, qui va garder les trous.
=> Tu le changes ensuite en simple champ numérique.
=> Tu crées un champ numéroauto dans la table (lui, il n'y aura plus de trous)
=> Tu mets à jour l'ancienne clé avec les valeurs de cette nouvelle colonne.
=> Tu détruits cette nouvelle colonne !
Evidement, tu pourras pas faire ça dans un trigger, je doute qu'il accepte que tu fasses un ALTER TABLE (surtout si c'est dans la table du trigger )
Marsh Posté le 29-07-2005 à 09:44:34
Ouch, g pas tt pigé à ton idée de génie, tu peux me la refaire la ?? pke ...
Quand est-ce que tu met le numéro auto ?
Quand est-ce que tu le change en simple champ ? ...
Sinon je creuse tjs la piste d'une jointure, sauf qu'on s'est rendu compte qu'on avait pas de colonne permettant cette jointure, donc pour une insertion de 16 lignes, la jointure nous sort 256 lignes -> y'a pas une requête qui empêche ça !
ex :
table idTrous table Prospect
13 paul,...
45 jacques,...
231 jean,....
686 yves,...
53145 pierre,...
et avoir comme table résultat :
13,paul,...
45,jacques,...
231,jean,....
686,yves,...
53145,pierre,...
Marsh Posté le 29-07-2005 à 11:08:28
Ma solution, en couleurs (enfin... en script )
Code :
|
Bon, OK, c'est un peu gore, d'autant plus si tu as des FK un peu partout qui utilisent ton id de la table prospects...
Marsh Posté le 29-07-2005 à 11:58:09
Bon ok ,avec le script j'ai pigé, mais le problème (Encore ??) c'est qu'on ne doit pas renuméroter les id de prospects parce qu'on les a imprimer sur des feuilles et qu'il doivent rester inchangé jusqu'à leur suppression de la base !
Enfin c'était une méthode hein
Pour l'instant, on fait ceçi :
Code :
|
Le seul problème c'est la table #tmpTest qui est générée avec une boucle qui dure surement plus de 2h ! C'est la seule solution qu'on a trouvé pour la créer !
Y'en a une autre plus facile pke passer 2h pour la création de cette table seulement, c'est pas top
Enfin sinon ca fnctionne
Marsh Posté le 26-07-2005 à 17:10:26
Bonjour à tous,
je suis actuellemnt dans les phases de tests grandeur nature de mon application php / SQL Server 2000.
Je dois notamment gérer une table d'une 20aines de champs (15 varchar, 3 dates ..., un index sur le n° de tel et un sur les autre champs de type varchar+les dates).
Elle contient les coordonnées de prospects, j'ai créé une procédure stockée permettant la mise à jour de ces données, elle-même contenue dans un travail planifié. Elle est chargée d'insérer dans une table temporaire tous les prospects récupérés dans un fichier texte à partir d'une autre application puis de les insérer en bloc (BULK INSERT) dans une table temporaire. Ensuite elle lis chaque ligne de cette table et vérifie que le numéro de téléphone n'est pas déjà enregistré dans la véritable table :
- s'il est présent et coché au rebut (BIT à 1), elle regarde alors si la ville, le code postal et le nom ne sont pas tout à fait ressemblant à ce qui est déjà présent (NOT LIKE), alors elle met à jour et enlève ce prospect des rebuts (BIT à 0), sinon elle met seulement à jour sans décoché le bit ;
- s'il est présent mais pas au rebut, elle le met à jour tout simplement.
Cette procédure (un peu compliqué mais nécessaire) permet d'éviter les doublons de n° de tél ainsi que des codes postaux non souhaités etc.
Lors du lancement de ces travaux, les fichiers de départ contiennent entre 10 000 et 70 000 lignes (donc prospects)
Ainsi la mise à jour d'une base vide (donc insertion dans les premiers temps) me donne ces résultats : 13 800 prospects dans la base en 34 min
puis 18 000 en 1h 20 etc
La mise à jour prend de plus en plus de temps, c'est tout à fait compréhensible puisqu'avant d'insérer une nouvelle ligne, la procédure doit scanner de plus en plus de données.
J'en arrive maintenant à quelques 300 000 prospects dans la base et la dernière mise à jour me donne : 57 800 prospects en 19h
Voilà à peu près mes résultats, mais j'aimerais savoir s'il était possible de les booster encore.
Je précise que SQL Server tourne sur un serveur cadencé à 3Ghz avec 1Go de RAM dédié à cette base et à la petite application php servant d'interface sous Win Server 2003. Il y aussi 2 DD de 73Go monté en RAID (enfin il me semble que c'est ce que HP nous a dit).
Enfin la base fait 90 Mo pour l'instant et le fichier de log en est à 750 Mo (je sais qu'on peut le nettoyer, comment faire et celà va-t-il regagner un peu de temps ??)
Merci d'avoir lu jusqu'ici, et de votre aide