Mise à jour, très bizarre.

Le
llopht
Bonjour à tous,

J'ai une table "statistiques" du genre :

tblStats
Id_Page (clé étrangère sur une table page)
int_Compteur
dtm_Date

Via la procédure stockée suivante et un fichier ASP je mets à jour cette
table environ 25 millions de fois par jour.

CREATE PRODECURE updStats

@IdPage int

AS
BEGIN
IF (SELECT count(int_Compteur) FROM tblStats WHERE dtm_Date =
fnc_CDate() AND Id_Page = @IdPage) = 0
BEGIN
INSERT INTO
tblStats (dtm_Date, Id_Page, int_Compteur)
VALUES
(fnc_CDate(), @IdPage, 1)
END
ELSE
BEGIN
UPDATE
tblStats
SET
int_Compteur = int_Compteur +1
WHERE
dtm_Date = fnc_CDate()
AND
Id_Page = @IdPage
END
END
GO

Pour info la fonction utilisateur fnc_CDate renvoie la date du jour au
format JJ/MM/YYYY.

J'ai deux petites questions :

- Est-ce la meilleure méthode ? Utiliser un insert serait probablement
plus rapide mais vu le nombre de ligne, je pense que c'est plus simple
d'utilisé un update (au pire il y a 300 pages)

- Je me retrouve avec des différences conséquentes entre le fichier de
log du serveur web et les valeurs de ma table. Est-ce le serveur web qui
décxxxx ou est-ce un problème de lock ou autre sur la table ?

Si quelqu'un pouvais me conseiller ?

merci !!

llopht
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fred BROUARD
Le #11856131
je ne voit pas l'intérêt de formater votre date puisque une date est un
type SQL date et n'a pas de format. Or l'utilisation d'une fonction est
couteuse.

votre table possède t-elle un index sur dtm-date + id_page ?
si non, il conviendrait d'en créer un.

enfin votre test conditionnel serait inutile si vous créez d'avance
toutes les lignes concernant le produit cartésien des pages et des dates
(jusqu'à 20 ans en avant, avec comme valeur du compteur 0.

Enfin, vous pouvez forcer un verrou de ligne afin d'éviter du
téléscopage de verrous dans les pages de la table

Avec tout cela votre code devrait se transformer en une unique requête
optimisée et rouler 2 à 1000 fois plus vite...

UPDATE tblStats WITH (ROWLOCK)
SET int_Compteur = int_Compteur +1
WHERE dtm_Date = FLOOR(CAST(CURRENT_TIMESTAMP AS FLOAT))
AND Id_Page = @IdPage

A +


llopht a écrit :
Bonjour à tous,

J'ai une table "statistiques" du genre :

tblStats
Id_Page (clé étrangère sur une table page)
int_Compteur
dtm_Date

Via la procédure stockée suivante et un fichier ASP je mets à jour cette
table environ 25 millions de fois par jour.

CREATE PRODECURE updStats

@IdPage int

AS
BEGIN
IF (SELECT count(int_Compteur) FROM tblStats WHERE dtm_Date =
fnc_CDate() AND Id_Page = @IdPage) = 0
BEGIN
INSERT INTO
tblStats (dtm_Date, Id_Page, int_Compteur)
VALUES
(fnc_CDate(), @IdPage, 1)
END
ELSE
BEGIN
UPDATE
tblStats
SET
int_Compteur = int_Compteur +1
WHERE
dtm_Date = fnc_CDate()
AND
Id_Page = @IdPage
END
END
GO

Pour info la fonction utilisateur fnc_CDate renvoie la date du jour au
format JJ/MM/YYYY.

J'ai deux petites questions :

- Est-ce la meilleure méthode ? Utiliser un insert serait probablement
plus rapide mais vu le nombre de ligne, je pense que c'est plus simple
d'utilisé un update (au pire il y a 300 pages)

- Je me retrouve avec des différences conséquentes entre le fichier de
log du serveur web et les valeurs de ma table. Est-ce le serveur web qui
décxxxx ou est-ce un problème de lock ou autre sur la table ?

Si quelqu'un pouvais me conseiller ?

merci !!

llopht





--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************
llopht
Le #11855991
> je ne voit pas l'intérêt de formater votre date puisque une date est un
type SQL date et n'a pas de format. Or l'utilisation d'une fonction est
couteuse.



Ben je suis développeur et pas spécialiste SQL Server donc j'ai un peu
l'habitude de mettre des fonctions partout :) Maintenant effectivement à
éviter pour perdre du temps.


votre table possède t-elle un index sur dtm-date + id_page ?
si non, il conviendrait d'en créer un.



Oui c'était déjà le cas. Je les ai mis décroissant.

enfin votre test conditionnel serait inutile si vous créez d'avance
toutes les lignes concernant le produit cartésien des pages et des dates
(jusqu'à 20 ans en avant, avec comme valeur du compteur 0.



Ah oui parfait, ça éviter le test et l'insertion. Mais deux petites
questions :

- Y a t'il (par hasard) des fonctions spécifiques en SQL pour calculer
le produit cartésien des deux ensembles.

- Vu que le nombre de pages et le temps évolue comment (tâche planifier)
ou tous les combiens recalculer ?

Enfin, vous pouvez forcer un verrou de ligne afin d'éviter du
téléscopage de verrous dans les pages de la table



Ok bon à savoir.

Merci Fred.

llopht
Fred BROUARD
Le #11855871
llopht a écrit :
je ne voit pas l'intérêt de formater votre date puisque une date est
un type SQL date et n'a pas de format. Or l'utilisation d'une fonction
est couteuse.



Ben je suis développeur et pas spécialiste SQL Server donc j'ai un peu
l'habitude de mettre des fonctions partout :) Maintenant effectivement à
éviter pour perdre du temps.


votre table possède t-elle un index sur dtm-date + id_page ?
si non, il conviendrait d'en créer un.



Oui c'était déjà le cas. Je les ai mis décroissant.

enfin votre test conditionnel serait inutile si vous créez d'avance
toutes les lignes concernant le produit cartésien des pages et des
dates (jusqu'à 20 ans en avant, avec comme valeur du compteur 0.



Ah oui parfait, ça éviter le test et l'insertion. Mais deux petites
questions :

- Y a t'il (par hasard) des fonctions spécifiques en SQL pour calculer
le produit cartésien des deux ensembles.



CROSS JOIN


- Vu que le nombre de pages et le temps évolue comment (tâche planifier)
ou tous les combiens recalculer ?



tous les ans, replacnifier 3 ans d'avance. Pour cela vous pouvez
utiliser l'agent SQL Server (tâche planifiée annuelle)


Enfin, vous pouvez forcer un verrou de ligne afin d'éviter du
téléscopage de verrous dans les pages de la table



Ok bon à savoir.



Oui, mais, piloter les verrous à la main, n'est pas toujours une bonne
chose ! Il faut le faire avec discernement. Dans votre cas si la table a
peu de ligne (quelques centaines au max) alors c'est bon.


Merci Fred.

llopht


A +

--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************
llopht
Publicité
Poster une réponse
Anonyme