Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Tu veux dire sans doute bannir les "curseurs" et non pas les "procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois pas
trop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" a écrit dans le message de
news:e8NlcD%23%Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
--------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
--------------------------------------- ----------------------------------------------------------------------
--------------------------------------- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
____________________________________________________________________________
_______________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
--------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
--------------------------------------- ----------------------------------------------------------------------
--------------------------------------- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Tu veux dire sans doute bannir les "curseurs" et non pas les "procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois pas
trop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
news:e8NlcD%23%23FHA.2740@tk2msftngp13.phx.gbl...
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
------------------------------------
--- ----------------------------------------------------------------------
------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
____________________________________________________________________________
_______________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
------------------------------------
--- ----------------------------------------------------------------------
------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Tu veux dire sans doute bannir les "curseurs" et non pas les "procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois pas
trop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" a écrit dans le message de
news:e8NlcD%23%Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
--------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
--------------------------------------- ----------------------------------------------------------------------
--------------------------------------- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
____________________________________________________________________________
_______________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
--------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
--------------------------------------- ----------------------------------------------------------------------
--------------------------------------- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ----------------------------------------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ----------------------------------------------------------------------
--- ----------------------------------------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
données avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%
> Tu veux dire sans doute bannir les "curseurs" et non pas les "procédures
> stockées" ?
>
> Ta procédure stockée fait également un traitement procédural ce qui est
> sans
> doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
> sont
> à "éviter" mais plutôt le traitement "procédural" par opposition aux
> traitements ensemblistes...
>
> Quel est ce fameux traitement ? N'est il pas réalisable avec une
> instruction
> SQL unique... Pour l'instant à part le flag et le comptage je ne vois
> trop ce que tu cherches à faire...
>
> Après il y a des cas où tu es sans doute obligé...
>
> --
> Patrice
>
> "MB" a écrit dans le message de
> news:e8NlcD%23%
>> Bonjour
>> Je sort d'une formation et le discours était
>> Bannir les procèdures stokées
>> Bannir les select *
>>
>> Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
>> les
>> curseurs vont plus vite et les select * aussi !
>>
>> voilà la méthode que l'on a utilisé
>> - voici un lien qui vous dira comment éviter les curseurs:
>> http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
>>
>>
>>
>> et voilà note test
>>
>> Avec curseur
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_NOM_IDE nvarchar(150)
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150)
>> DECLARE @nvc_DEBUT_NOM nvarchar(10)
>> DECLARE @int_PAT_SEXE int
>> DECLARE @int_PAT_NAI_JJ int
>> DECLARE @int_PAT_NAI_MM int
>> DECLARE @int_PAT_NAI_AA int
>> DECLARE @int_IDE_CLE int
>>
>>
>> DECLARE @nvc_USG_CLE nvarchar(150)
>> DECLARE @cpt int
>>
>>--- ---------------------------------------------------------------------
> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
>> END
>>
>> SET @cpt = 0
>>--- ---------------------------------------------------------------------
> --------------------------------------- ---------------------------------------------------------------------
> ------------------------------------
>> --- Ouverture du curseur de parcours des enregistrements
>>
>> DECLARE cur_CleIdentite CURSOR
>> FOR
>> SELECT
>> CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE
>>
>> OPEN cur_CleIdentite
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>>
>> WHILE @@FETCH_STATUS = 0
>> begin
>>
>>
>> --- ***************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>> --- ********************************************************
>>
>>
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>> End
>>
>> --- fermeture du curseur
>>
>> Close cur_CleIdentite
>> DEALLOCATE cur_CleIdentite
>>
>> print @cpt
>>
>>
>>
>
> _______________
>>
>>
>> SANS CURSOR
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_PRE_IDE nvarchar(150);
>> DECLARE @nvc_NOM_IDE nvarchar(150);
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150);
>> DECLARE @nvc_DEBUT_NOM nvarchar(10);
>> DECLARE @int_PAT_SEXE int;
>> DECLARE @int_PAT_NAI_JJ int;
>> DECLARE @int_PAT_NAI_MM int;
>> DECLARE @int_PAT_NAI_AA int;
>> DECLARE @int_IDE_CLE int;
>> DECLARE @cpt int;
>>
>>--- ---------------------------------------------------------------------
> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE;
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
>>
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
>> END;
>>
>>
>> SET @cpt = 0;
>>--- ---------------------------------------------------------------------
> --------------------------------------- ---------------------------------------------------------------------
> ------------------------------------
>> --- On stocke les clé des identités dans une table temporaire
>>
>> SELECT
>> CLE_IDE,
>> 0 AS OK
>> INTO #TMP_CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE;
>>
>> -- tant qu'il y a au moins une table à traiter
>> WHILE EXISTS(
>> SELECT
>> CLE_IDE
>> FROM #TMP_CLE_IDE
>> WHERE OK = 0)
>> BEGIN
>>
>> -- prendre la clé de la première identité à traiter
>> SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
>> FROM #TMP_CLE_IDE WHERE OK = 0
>> ORDER BY 1);
>>
>>
>> ---
>> ********************************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>>
>> ---
>> ********************************************************************
>>
>>
>>
>>
>> -- flaguer l'objet traité dans la table des objets à traiter
>> UPDATE #TMP_CLE_IDE
>> SET OK = 1
>> WHERE CLE_IDE = @int_IDE_CLE;
>>
>> --- Fin de la boucle WHILE
>> END;
>>
>>
>> -- supprimez la table temporaire de traitement
>> DROP TABLE #TMP_CLE_IDE;
>>
>> print @cpt
>>
>>
>> voilou
>>
>>
>>
>>
>
>
Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
données avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" <nobody@nowhere.com> a écrit dans le message de news:
%23dzFYb%23%23FHA.3464@TK2MSFTNGP15.phx.gbl...
> Tu veux dire sans doute bannir les "curseurs" et non pas les "procédures
> stockées" ?
>
> Ta procédure stockée fait également un traitement procédural ce qui est
> sans
> doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
> sont
> à "éviter" mais plutôt le traitement "procédural" par opposition aux
> traitements ensemblistes...
>
> Quel est ce fameux traitement ? N'est il pas réalisable avec une
> instruction
> SQL unique... Pour l'instant à part le flag et le comptage je ne vois
> trop ce que tu cherches à faire...
>
> Après il y a des cas où tu es sans doute obligé...
>
> --
> Patrice
>
> "MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
> news:e8NlcD%23%23FHA.2740@tk2msftngp13.phx.gbl...
>> Bonjour
>> Je sort d'une formation et le discours était
>> Bannir les procèdures stokées
>> Bannir les select *
>>
>> Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
>> les
>> curseurs vont plus vite et les select * aussi !
>>
>> voilà la méthode que l'on a utilisé
>> - voici un lien qui vous dira comment éviter les curseurs:
>> http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
>>
>>
>>
>> et voilà note test
>>
>> Avec curseur
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_NOM_IDE nvarchar(150)
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150)
>> DECLARE @nvc_DEBUT_NOM nvarchar(10)
>> DECLARE @int_PAT_SEXE int
>> DECLARE @int_PAT_NAI_JJ int
>> DECLARE @int_PAT_NAI_MM int
>> DECLARE @int_PAT_NAI_AA int
>> DECLARE @int_IDE_CLE int
>>
>>
>> DECLARE @nvc_USG_CLE nvarchar(150)
>> DECLARE @cpt int
>>
>>
--- ---------------------------------------------------------------------
> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
>> END
>>
>> SET @cpt = 0
>>
--- ---------------------------------------------------------------------
> ------------------------------------
--- ---------------------------------------------------------------------
> ------------------------------------
>> --- Ouverture du curseur de parcours des enregistrements
>>
>> DECLARE cur_CleIdentite CURSOR
>> FOR
>> SELECT
>> CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE
>>
>> OPEN cur_CleIdentite
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>>
>> WHILE @@FETCH_STATUS = 0
>> begin
>>
>>
>> --- ***************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>> --- ********************************************************
>>
>>
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>> End
>>
>> --- fermeture du curseur
>>
>> Close cur_CleIdentite
>> DEALLOCATE cur_CleIdentite
>>
>> print @cpt
>>
>>
>>
>
> _______________
>>
>>
>> SANS CURSOR
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_PRE_IDE nvarchar(150);
>> DECLARE @nvc_NOM_IDE nvarchar(150);
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150);
>> DECLARE @nvc_DEBUT_NOM nvarchar(10);
>> DECLARE @int_PAT_SEXE int;
>> DECLARE @int_PAT_NAI_JJ int;
>> DECLARE @int_PAT_NAI_MM int;
>> DECLARE @int_PAT_NAI_AA int;
>> DECLARE @int_IDE_CLE int;
>> DECLARE @cpt int;
>>
>>
--- ---------------------------------------------------------------------
> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE;
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
>>
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
>> END;
>>
>>
>> SET @cpt = 0;
>>
--- ---------------------------------------------------------------------
> ------------------------------------
--- ---------------------------------------------------------------------
> ------------------------------------
>> --- On stocke les clé des identités dans une table temporaire
>>
>> SELECT
>> CLE_IDE,
>> 0 AS OK
>> INTO #TMP_CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE;
>>
>> -- tant qu'il y a au moins une table à traiter
>> WHILE EXISTS(
>> SELECT
>> CLE_IDE
>> FROM #TMP_CLE_IDE
>> WHERE OK = 0)
>> BEGIN
>>
>> -- prendre la clé de la première identité à traiter
>> SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
>> FROM #TMP_CLE_IDE WHERE OK = 0
>> ORDER BY 1);
>>
>>
>> ---
>> ********************************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>>
>> ---
>> ********************************************************************
>>
>>
>>
>>
>> -- flaguer l'objet traité dans la table des objets à traiter
>> UPDATE #TMP_CLE_IDE
>> SET OK = 1
>> WHERE CLE_IDE = @int_IDE_CLE;
>>
>> --- Fin de la boucle WHILE
>> END;
>>
>>
>> -- supprimez la table temporaire de traitement
>> DROP TABLE #TMP_CLE_IDE;
>>
>> print @cpt
>>
>>
>> voilou
>>
>>
>>
>>
>
>
Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
données avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%
> Tu veux dire sans doute bannir les "curseurs" et non pas les "procédures
> stockées" ?
>
> Ta procédure stockée fait également un traitement procédural ce qui est
> sans
> doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
> sont
> à "éviter" mais plutôt le traitement "procédural" par opposition aux
> traitements ensemblistes...
>
> Quel est ce fameux traitement ? N'est il pas réalisable avec une
> instruction
> SQL unique... Pour l'instant à part le flag et le comptage je ne vois
> trop ce que tu cherches à faire...
>
> Après il y a des cas où tu es sans doute obligé...
>
> --
> Patrice
>
> "MB" a écrit dans le message de
> news:e8NlcD%23%
>> Bonjour
>> Je sort d'une formation et le discours était
>> Bannir les procèdures stokées
>> Bannir les select *
>>
>> Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
>> les
>> curseurs vont plus vite et les select * aussi !
>>
>> voilà la méthode que l'on a utilisé
>> - voici un lien qui vous dira comment éviter les curseurs:
>> http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
>>
>>
>>
>> et voilà note test
>>
>> Avec curseur
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_NOM_IDE nvarchar(150)
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150)
>> DECLARE @nvc_DEBUT_NOM nvarchar(10)
>> DECLARE @int_PAT_SEXE int
>> DECLARE @int_PAT_NAI_JJ int
>> DECLARE @int_PAT_NAI_MM int
>> DECLARE @int_PAT_NAI_AA int
>> DECLARE @int_IDE_CLE int
>>
>>
>> DECLARE @nvc_USG_CLE nvarchar(150)
>> DECLARE @cpt int
>>
>>--- ---------------------------------------------------------------------
> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
>> END
>>
>> SET @cpt = 0
>>--- ---------------------------------------------------------------------
> --------------------------------------- ---------------------------------------------------------------------
> ------------------------------------
>> --- Ouverture du curseur de parcours des enregistrements
>>
>> DECLARE cur_CleIdentite CURSOR
>> FOR
>> SELECT
>> CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE
>>
>> OPEN cur_CleIdentite
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>>
>> WHILE @@FETCH_STATUS = 0
>> begin
>>
>>
>> --- ***************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>> --- ********************************************************
>>
>>
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>> End
>>
>> --- fermeture du curseur
>>
>> Close cur_CleIdentite
>> DEALLOCATE cur_CleIdentite
>>
>> print @cpt
>>
>>
>>
>
> _______________
>>
>>
>> SANS CURSOR
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_PRE_IDE nvarchar(150);
>> DECLARE @nvc_NOM_IDE nvarchar(150);
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150);
>> DECLARE @nvc_DEBUT_NOM nvarchar(10);
>> DECLARE @int_PAT_SEXE int;
>> DECLARE @int_PAT_NAI_JJ int;
>> DECLARE @int_PAT_NAI_MM int;
>> DECLARE @int_PAT_NAI_AA int;
>> DECLARE @int_IDE_CLE int;
>> DECLARE @cpt int;
>>
>>--- ---------------------------------------------------------------------
> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE;
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
>>
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
>> END;
>>
>>
>> SET @cpt = 0;
>>--- ---------------------------------------------------------------------
> --------------------------------------- ---------------------------------------------------------------------
> ------------------------------------
>> --- On stocke les clé des identités dans une table temporaire
>>
>> SELECT
>> CLE_IDE,
>> 0 AS OK
>> INTO #TMP_CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE;
>>
>> -- tant qu'il y a au moins une table à traiter
>> WHILE EXISTS(
>> SELECT
>> CLE_IDE
>> FROM #TMP_CLE_IDE
>> WHERE OK = 0)
>> BEGIN
>>
>> -- prendre la clé de la première identité à traiter
>> SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
>> FROM #TMP_CLE_IDE WHERE OK = 0
>> ORDER BY 1);
>>
>>
>> ---
>> ********************************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>>
>> ---
>> ********************************************************************
>>
>>
>>
>>
>> -- flaguer l'objet traité dans la table des objets à traiter
>> UPDATE #TMP_CLE_IDE
>> SET OK = 1
>> WHERE CLE_IDE = @int_IDE_CLE;
>>
>> --- Fin de la boucle WHILE
>> END;
>>
>>
>> -- supprimez la table temporaire de traitement
>> DROP TABLE #TMP_CLE_IDE;
>>
>> print @cpt
>>
>>
>> voilou
>>
>>
>>
>>
>
>
Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE) ?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" a écrit dans le message de
news:OzJYvU$%Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
dedonnées avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%
> Tu veux dire sans doute bannir les "curseurs" et non pas les
> "procédures
> stockées" ?
>
> Ta procédure stockée fait également un traitement procédural ce qui est
> sans
> doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
> sont
> à "éviter" mais plutôt le traitement "procédural" par opposition aux
> traitements ensemblistes...
>
> Quel est ce fameux traitement ? N'est il pas réalisable avec une
> instruction
> SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pas> trop ce que tu cherches à faire...
>
> Après il y a des cas où tu es sans doute obligé...
>
> --
> Patrice
>
> "MB" a écrit dans le message de
> news:e8NlcD%23%
>> Bonjour
>> Je sort d'une formation et le discours était
>> Bannir les procèdures stokées
>> Bannir les select *
>>
>> Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
>> les
>> curseurs vont plus vite et les select * aussi !
>>
>> voilà la méthode que l'on a utilisé
>> - voici un lien qui vous dira comment éviter les curseurs:
>> http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
>>
>>
>>
>> et voilà note test
>>
>> Avec curseur
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_NOM_IDE nvarchar(150)
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150)
>> DECLARE @nvc_DEBUT_NOM nvarchar(10)
>> DECLARE @int_PAT_SEXE int
>> DECLARE @int_PAT_NAI_JJ int
>> DECLARE @int_PAT_NAI_MM int
>> DECLARE @int_PAT_NAI_AA int
>> DECLARE @int_IDE_CLE int
>>
>>
>> DECLARE @nvc_USG_CLE nvarchar(150)
>> DECLARE @cpt int
>>
>>--- ---------------------------------------------------------------------
-> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
>> END
>>
>> SET @cpt = 0
>>--- ---------------------------------------------------------------------
-> --------------------------------------- ---------------------------------------------------------------------
-> ------------------------------------
>> --- Ouverture du curseur de parcours des enregistrements
>>
>> DECLARE cur_CleIdentite CURSOR
>> FOR
>> SELECT
>> CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE
>>
>> OPEN cur_CleIdentite
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>>
>> WHILE @@FETCH_STATUS = 0
>> begin
>>
>>
>> --- ***************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>> --- ********************************************************
>>
>>
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>> End
>>
>> --- fermeture du curseur
>>
>> Close cur_CleIdentite
>> DEALLOCATE cur_CleIdentite
>>
>> print @cpt
>>
>>
>>
>
____________________________________________________________________________> _______________
>>
>>
>> SANS CURSOR
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_PRE_IDE nvarchar(150);
>> DECLARE @nvc_NOM_IDE nvarchar(150);
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150);
>> DECLARE @nvc_DEBUT_NOM nvarchar(10);
>> DECLARE @int_PAT_SEXE int;
>> DECLARE @int_PAT_NAI_JJ int;
>> DECLARE @int_PAT_NAI_MM int;
>> DECLARE @int_PAT_NAI_AA int;
>> DECLARE @int_IDE_CLE int;
>> DECLARE @cpt int;
>>
>>--- ---------------------------------------------------------------------
-> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE;
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
>>
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
>> END;
>>
>>
>> SET @cpt = 0;
>>--- ---------------------------------------------------------------------
-> --------------------------------------- ---------------------------------------------------------------------
-> ------------------------------------
>> --- On stocke les clé des identités dans une table temporaire
>>
>> SELECT
>> CLE_IDE,
>> 0 AS OK
>> INTO #TMP_CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE;
>>
>> -- tant qu'il y a au moins une table à traiter
>> WHILE EXISTS(
>> SELECT
>> CLE_IDE
>> FROM #TMP_CLE_IDE
>> WHERE OK = 0)
>> BEGIN
>>
>> -- prendre la clé de la première identité à traiter
>> SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
>> FROM #TMP_CLE_IDE WHERE OK = 0
>> ORDER BY 1);
>>
>>
>> ---
>> ********************************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>>
>> ---
>> ********************************************************************
>>
>>
>>
>>
>> -- flaguer l'objet traité dans la table des objets à traiter
>> UPDATE #TMP_CLE_IDE
>> SET OK = 1
>> WHERE CLE_IDE = @int_IDE_CLE;
>>
>> --- Fin de la boucle WHILE
>> END;
>>
>>
>> -- supprimez la table temporaire de traitement
>> DROP TABLE #TMP_CLE_IDE;
>>
>> print @cpt
>>
>>
>> voilou
>>
>>
>>
>>
>
>
Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE) ?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
news:OzJYvU$%23FHA.160@TK2MSFTNGP12.phx.gbl...
Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
de
données avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" <nobody@nowhere.com> a écrit dans le message de news:
%23dzFYb%23%23FHA.3464@TK2MSFTNGP15.phx.gbl...
> Tu veux dire sans doute bannir les "curseurs" et non pas les
> "procédures
> stockées" ?
>
> Ta procédure stockée fait également un traitement procédural ce qui est
> sans
> doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
> sont
> à "éviter" mais plutôt le traitement "procédural" par opposition aux
> traitements ensemblistes...
>
> Quel est ce fameux traitement ? N'est il pas réalisable avec une
> instruction
> SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pas
> trop ce que tu cherches à faire...
>
> Après il y a des cas où tu es sans doute obligé...
>
> --
> Patrice
>
> "MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
> news:e8NlcD%23%23FHA.2740@tk2msftngp13.phx.gbl...
>> Bonjour
>> Je sort d'une formation et le discours était
>> Bannir les procèdures stokées
>> Bannir les select *
>>
>> Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
>> les
>> curseurs vont plus vite et les select * aussi !
>>
>> voilà la méthode que l'on a utilisé
>> - voici un lien qui vous dira comment éviter les curseurs:
>> http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
>>
>>
>>
>> et voilà note test
>>
>> Avec curseur
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_NOM_IDE nvarchar(150)
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150)
>> DECLARE @nvc_DEBUT_NOM nvarchar(10)
>> DECLARE @int_PAT_SEXE int
>> DECLARE @int_PAT_NAI_JJ int
>> DECLARE @int_PAT_NAI_MM int
>> DECLARE @int_PAT_NAI_AA int
>> DECLARE @int_IDE_CLE int
>>
>>
>> DECLARE @nvc_USG_CLE nvarchar(150)
>> DECLARE @cpt int
>>
>>
--- ---------------------------------------------------------------------
-
> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
>> END
>>
>> SET @cpt = 0
>>
--- ---------------------------------------------------------------------
-
> ------------------------------------
--- ---------------------------------------------------------------------
-
> ------------------------------------
>> --- Ouverture du curseur de parcours des enregistrements
>>
>> DECLARE cur_CleIdentite CURSOR
>> FOR
>> SELECT
>> CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE
>>
>> OPEN cur_CleIdentite
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>>
>> WHILE @@FETCH_STATUS = 0
>> begin
>>
>>
>> --- ***************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>> --- ********************************************************
>>
>>
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>> End
>>
>> --- fermeture du curseur
>>
>> Close cur_CleIdentite
>> DEALLOCATE cur_CleIdentite
>>
>> print @cpt
>>
>>
>>
>
____________________________________________________________________________
> _______________
>>
>>
>> SANS CURSOR
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_PRE_IDE nvarchar(150);
>> DECLARE @nvc_NOM_IDE nvarchar(150);
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150);
>> DECLARE @nvc_DEBUT_NOM nvarchar(10);
>> DECLARE @int_PAT_SEXE int;
>> DECLARE @int_PAT_NAI_JJ int;
>> DECLARE @int_PAT_NAI_MM int;
>> DECLARE @int_PAT_NAI_AA int;
>> DECLARE @int_IDE_CLE int;
>> DECLARE @cpt int;
>>
>>
--- ---------------------------------------------------------------------
-
> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE;
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
>>
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
>> END;
>>
>>
>> SET @cpt = 0;
>>
--- ---------------------------------------------------------------------
-
> ------------------------------------
--- ---------------------------------------------------------------------
-
> ------------------------------------
>> --- On stocke les clé des identités dans une table temporaire
>>
>> SELECT
>> CLE_IDE,
>> 0 AS OK
>> INTO #TMP_CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE;
>>
>> -- tant qu'il y a au moins une table à traiter
>> WHILE EXISTS(
>> SELECT
>> CLE_IDE
>> FROM #TMP_CLE_IDE
>> WHERE OK = 0)
>> BEGIN
>>
>> -- prendre la clé de la première identité à traiter
>> SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
>> FROM #TMP_CLE_IDE WHERE OK = 0
>> ORDER BY 1);
>>
>>
>> ---
>> ********************************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>>
>> ---
>> ********************************************************************
>>
>>
>>
>>
>> -- flaguer l'objet traité dans la table des objets à traiter
>> UPDATE #TMP_CLE_IDE
>> SET OK = 1
>> WHERE CLE_IDE = @int_IDE_CLE;
>>
>> --- Fin de la boucle WHILE
>> END;
>>
>>
>> -- supprimez la table temporaire de traitement
>> DROP TABLE #TMP_CLE_IDE;
>>
>> print @cpt
>>
>>
>> voilou
>>
>>
>>
>>
>
>
Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE) ?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" a écrit dans le message de
news:OzJYvU$%Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
dedonnées avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%
> Tu veux dire sans doute bannir les "curseurs" et non pas les
> "procédures
> stockées" ?
>
> Ta procédure stockée fait également un traitement procédural ce qui est
> sans
> doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
> sont
> à "éviter" mais plutôt le traitement "procédural" par opposition aux
> traitements ensemblistes...
>
> Quel est ce fameux traitement ? N'est il pas réalisable avec une
> instruction
> SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pas> trop ce que tu cherches à faire...
>
> Après il y a des cas où tu es sans doute obligé...
>
> --
> Patrice
>
> "MB" a écrit dans le message de
> news:e8NlcD%23%
>> Bonjour
>> Je sort d'une formation et le discours était
>> Bannir les procèdures stokées
>> Bannir les select *
>>
>> Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
>> les
>> curseurs vont plus vite et les select * aussi !
>>
>> voilà la méthode que l'on a utilisé
>> - voici un lien qui vous dira comment éviter les curseurs:
>> http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
>>
>>
>>
>> et voilà note test
>>
>> Avec curseur
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_NOM_IDE nvarchar(150)
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150)
>> DECLARE @nvc_DEBUT_NOM nvarchar(10)
>> DECLARE @int_PAT_SEXE int
>> DECLARE @int_PAT_NAI_JJ int
>> DECLARE @int_PAT_NAI_MM int
>> DECLARE @int_PAT_NAI_AA int
>> DECLARE @int_IDE_CLE int
>>
>>
>> DECLARE @nvc_USG_CLE nvarchar(150)
>> DECLARE @cpt int
>>
>>--- ---------------------------------------------------------------------
-> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
>> END
>>
>> SET @cpt = 0
>>--- ---------------------------------------------------------------------
-> --------------------------------------- ---------------------------------------------------------------------
-> ------------------------------------
>> --- Ouverture du curseur de parcours des enregistrements
>>
>> DECLARE cur_CleIdentite CURSOR
>> FOR
>> SELECT
>> CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE
>>
>> OPEN cur_CleIdentite
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>>
>> WHILE @@FETCH_STATUS = 0
>> begin
>>
>>
>> --- ***************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>> --- ********************************************************
>>
>>
>>
>> FETCH NEXT FROM cur_CleIdentite
>> INTO @int_IDE_CLE
>> End
>>
>> --- fermeture du curseur
>>
>> Close cur_CleIdentite
>> DEALLOCATE cur_CleIdentite
>>
>> print @cpt
>>
>>
>>
>
____________________________________________________________________________> _______________
>>
>>
>> SANS CURSOR
>>
>>
>> DECLARE @nvc_PRE_IDE nvarchar(150)
>> DECLARE @nvc_PRE_IDE nvarchar(150);
>> DECLARE @nvc_NOM_IDE nvarchar(150);
>> DECLARE @nvc_PAT_NOM_JF nvarchar(150);
>> DECLARE @nvc_DEBUT_NOM nvarchar(10);
>> DECLARE @int_PAT_SEXE int;
>> DECLARE @int_PAT_NAI_JJ int;
>> DECLARE @int_PAT_NAI_MM int;
>> DECLARE @int_PAT_NAI_AA int;
>> DECLARE @int_IDE_CLE int;
>> DECLARE @cpt int;
>>
>>--- ---------------------------------------------------------------------
-> ------------------------------------
>> --- On efface les anciens enregistrements de la base
>>
>> DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
>> WHERE USG_CLE = @nvc_USG_CLE;
>>
>> SELECT
>> @cpt = count(*)
>> FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
>>
>>
>> IF @cpt = 0
>> BEGIN
>> TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
>> END;
>>
>>
>> SET @cpt = 0;
>>--- ---------------------------------------------------------------------
-> --------------------------------------- ---------------------------------------------------------------------
-> ------------------------------------
>> --- On stocke les clé des identités dans une table temporaire
>>
>> SELECT
>> CLE_IDE,
>> 0 AS OK
>> INTO #TMP_CLE_IDE
>> FROM ADR_TAB_IDENTITES
>> ORDER BY CLE_IDE;
>>
>> -- tant qu'il y a au moins une table à traiter
>> WHILE EXISTS(
>> SELECT
>> CLE_IDE
>> FROM #TMP_CLE_IDE
>> WHERE OK = 0)
>> BEGIN
>>
>> -- prendre la clé de la première identité à traiter
>> SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
>> FROM #TMP_CLE_IDE WHERE OK = 0
>> ORDER BY 1);
>>
>>
>> ---
>> ********************************************************************
>> --- Corps du programme
>> SET @cpt = @cpt + 1
>>
>> ---
>> ********************************************************************
>>
>>
>>
>>
>> -- flaguer l'objet traité dans la table des objets à traiter
>> UPDATE #TMP_CLE_IDE
>> SET OK = 1
>> WHERE CLE_IDE = @int_IDE_CLE;
>>
>> --- Fin de la boucle WHILE
>> END;
>>
>>
>> -- supprimez la table temporaire de traitement
>> DROP TABLE #TMP_CLE_IDE;
>>
>> print @cpt
>>
>>
>> voilou
>>
>>
>>
>>
>
>
Dans quel cas on est dans de la programmation *ensembliste*
Merci
"Patrice" a écrit dans le message de news:
eG1Pwy$%Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE) ?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" a écrit dans le message de
news:OzJYvU$%Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
dedonnées avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pastrop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" a écrit dans le message de
news:e8NlcD%23%Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
___________________________________________________________________________________________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Dans quel cas on est dans de la programmation *ensembliste*
Merci
"Patrice" <nobody@nowhere.com> a écrit dans le message de news:
eG1Pwy$%23FHA.2812@TK2MSFTNGP09.phx.gbl...
Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE) ?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
news:OzJYvU$%23FHA.160@TK2MSFTNGP12.phx.gbl...
Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
de
données avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" <nobody@nowhere.com> a écrit dans le message de news:
%23dzFYb%23%23FHA.3464@TK2MSFTNGP15.phx.gbl...
Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pas
trop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
news:e8NlcD%23%23FHA.2740@tk2msftngp13.phx.gbl...
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ---------------------------------------------------------------------
-
------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ---------------------------------------------------------------------
-
------------------------------------
--- ---------------------------------------------------------------------
-
------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
____________________________________________________________________________
_______________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ---------------------------------------------------------------------
-
------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ---------------------------------------------------------------------
-
------------------------------------
--- ---------------------------------------------------------------------
-
------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
Dans quel cas on est dans de la programmation *ensembliste*
Merci
"Patrice" a écrit dans le message de news:
eG1Pwy$%Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE) ?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" a écrit dans le message de
news:OzJYvU$%Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
dedonnées avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pastrop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" a écrit dans le message de
news:e8NlcD%23%Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
___________________________________________________________________________________________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
bonjour,
MB a écrit:Dans quel cas on est dans de la programmation *ensembliste*
Merci
1) lorsque TOUT le traitement est fait à l'aide d'une seule et unique
requête (UPDATE, INSERT, DELETE ou SELECT)
2) lorsqu'il y a une requête encapsulant des vues ou des expressions de
table (CTE)
3) lorsque le code n'a aucun branchement : notamment dans le cas de
requêtes SQL enchaînées pour des mises à jour combinées (par exemple table
fille + table mère).
Sinon, effectivement l'exemple choisit pour comparaison n'a pas de réel
intérêt : dans les deux cas il y a du procédural. De plus pour mesurer
l'intérêt de la chose il faut comparer avec plus ou moins de volume :
1) 500 lignes
2) 5 000 lignes
3) 50 000 lignes
4) 500 000 lignes
5) 5 000 000 lignes
en faisant en sorte que le volume dépasse la RAM disponible pour voir
quels sont les effets du cache de données.
A +
"Patrice" a écrit dans le message de news:
eG1Pwy$%Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE)
?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" a écrit dans le message de
news:OzJYvU$%Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
dedonnées avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pastrop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" a écrit dans le message de
news:e8NlcD%23%Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
___________________________________________________________________________________________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
--
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 ***********************
bonjour,
MB a écrit:
Dans quel cas on est dans de la programmation *ensembliste*
Merci
1) lorsque TOUT le traitement est fait à l'aide d'une seule et unique
requête (UPDATE, INSERT, DELETE ou SELECT)
2) lorsqu'il y a une requête encapsulant des vues ou des expressions de
table (CTE)
3) lorsque le code n'a aucun branchement : notamment dans le cas de
requêtes SQL enchaînées pour des mises à jour combinées (par exemple table
fille + table mère).
Sinon, effectivement l'exemple choisit pour comparaison n'a pas de réel
intérêt : dans les deux cas il y a du procédural. De plus pour mesurer
l'intérêt de la chose il faut comparer avec plus ou moins de volume :
1) 500 lignes
2) 5 000 lignes
3) 50 000 lignes
4) 500 000 lignes
5) 5 000 000 lignes
en faisant en sorte que le volume dépasse la RAM disponible pour voir
quels sont les effets du cache de données.
A +
"Patrice" <nobody@nowhere.com> a écrit dans le message de news:
eG1Pwy$%23FHA.2812@TK2MSFTNGP09.phx.gbl...
Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE)
?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
news:OzJYvU$%23FHA.160@TK2MSFTNGP12.phx.gbl...
Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
de
données avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" <nobody@nowhere.com> a écrit dans le message de news:
%23dzFYb%23%23FHA.3464@TK2MSFTNGP15.phx.gbl...
Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pas
trop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
news:e8NlcD%23%23FHA.2740@tk2msftngp13.phx.gbl...
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ---------------------------------------------------------------------
-
------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ---------------------------------------------------------------------
-
------------------------------------
--- ---------------------------------------------------------------------
-
------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
____________________________________________________________________________
_______________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ---------------------------------------------------------------------
-
------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ---------------------------------------------------------------------
-
------------------------------------
--- ---------------------------------------------------------------------
-
------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
--
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 ***********************
bonjour,
MB a écrit:Dans quel cas on est dans de la programmation *ensembliste*
Merci
1) lorsque TOUT le traitement est fait à l'aide d'une seule et unique
requête (UPDATE, INSERT, DELETE ou SELECT)
2) lorsqu'il y a une requête encapsulant des vues ou des expressions de
table (CTE)
3) lorsque le code n'a aucun branchement : notamment dans le cas de
requêtes SQL enchaînées pour des mises à jour combinées (par exemple table
fille + table mère).
Sinon, effectivement l'exemple choisit pour comparaison n'a pas de réel
intérêt : dans les deux cas il y a du procédural. De plus pour mesurer
l'intérêt de la chose il faut comparer avec plus ou moins de volume :
1) 500 lignes
2) 5 000 lignes
3) 50 000 lignes
4) 500 000 lignes
5) 5 000 000 lignes
en faisant en sorte que le volume dépasse la RAM disponible pour voir
quels sont les effets du cache de données.
A +
"Patrice" a écrit dans le message de news:
eG1Pwy$%Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE)
?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" a écrit dans le message de
news:OzJYvU$%Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
dedonnées avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pastrop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" a écrit dans le message de
news:e8NlcD%23%Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
___________________________________________________________________________________________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
--
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 ***********************
Merci
On va pousser un peu plus loin nos tests de performance
"Fred BROUARD" a écrit dans le message de news:
enoD$%23A$bonjour,
MB a écrit:Dans quel cas on est dans de la programmation *ensembliste*
Merci
1) lorsque TOUT le traitement est fait à l'aide d'une seule et unique
requête (UPDATE, INSERT, DELETE ou SELECT)
2) lorsqu'il y a une requête encapsulant des vues ou des expressions de
table (CTE)
3) lorsque le code n'a aucun branchement : notamment dans le cas de
requêtes SQL enchaînées pour des mises à jour combinées (par exemple table
fille + table mère).
Sinon, effectivement l'exemple choisit pour comparaison n'a pas de réel
intérêt : dans les deux cas il y a du procédural. De plus pour mesurer
l'intérêt de la chose il faut comparer avec plus ou moins de volume :
1) 500 lignes
2) 5 000 lignes
3) 50 000 lignes
4) 500 000 lignes
5) 5 000 000 lignes
en faisant en sorte que le volume dépasse la RAM disponible pour voir
quels sont les effets du cache de données.
A +"Patrice" a écrit dans le message de news:
eG1Pwy$%Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE)
?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" a écrit dans le message de
news:OzJYvU$%Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
dedonnées avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pastrop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" a écrit dans le message de
news:e8NlcD%23%Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
___________________________________________________________________________________________SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
--
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 ***********************
Merci
On va pousser un peu plus loin nos tests de performance
"Fred BROUARD" <brouardf@club-internet.fr> a écrit dans le message de news:
enoD$%23A$FHA.740@TK2MSFTNGP12.phx.gbl...
bonjour,
MB a écrit:
Dans quel cas on est dans de la programmation *ensembliste*
Merci
1) lorsque TOUT le traitement est fait à l'aide d'une seule et unique
requête (UPDATE, INSERT, DELETE ou SELECT)
2) lorsqu'il y a une requête encapsulant des vues ou des expressions de
table (CTE)
3) lorsque le code n'a aucun branchement : notamment dans le cas de
requêtes SQL enchaînées pour des mises à jour combinées (par exemple table
fille + table mère).
Sinon, effectivement l'exemple choisit pour comparaison n'a pas de réel
intérêt : dans les deux cas il y a du procédural. De plus pour mesurer
l'intérêt de la chose il faut comparer avec plus ou moins de volume :
1) 500 lignes
2) 5 000 lignes
3) 50 000 lignes
4) 500 000 lignes
5) 5 000 000 lignes
en faisant en sorte que le volume dépasse la RAM disponible pour voir
quels sont les effets du cache de données.
A +
"Patrice" <nobody@nowhere.com> a écrit dans le message de news:
eG1Pwy$%23FHA.2812@TK2MSFTNGP09.phx.gbl...
Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE)
?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
news:OzJYvU$%23FHA.160@TK2MSFTNGP12.phx.gbl...
Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
de
données avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" <nobody@nowhere.com> a écrit dans le message de news:
%23dzFYb%23%23FHA.3464@TK2MSFTNGP15.phx.gbl...
Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pas
trop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" <michel.boudat@isped.u-bordeaux2.fr> a écrit dans le message de
news:e8NlcD%23%23FHA.2740@tk2msftngp13.phx.gbl...
Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int
--- ---------------------------------------------------------------------
-
------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0
--- ---------------------------------------------------------------------
-
------------------------------------
--- ---------------------------------------------------------------------
-
------------------------------------
--- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
____________________________________________________________________________
_______________
SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;
--- ---------------------------------------------------------------------
-
------------------------------------
--- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;
--- ---------------------------------------------------------------------
-
------------------------------------
--- ---------------------------------------------------------------------
-
------------------------------------
--- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
--
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 ***********************
Merci
On va pousser un peu plus loin nos tests de performance
"Fred BROUARD" a écrit dans le message de news:
enoD$%23A$bonjour,
MB a écrit:Dans quel cas on est dans de la programmation *ensembliste*
Merci
1) lorsque TOUT le traitement est fait à l'aide d'une seule et unique
requête (UPDATE, INSERT, DELETE ou SELECT)
2) lorsqu'il y a une requête encapsulant des vues ou des expressions de
table (CTE)
3) lorsque le code n'a aucun branchement : notamment dans le cas de
requêtes SQL enchaînées pour des mises à jour combinées (par exemple table
fille + table mère).
Sinon, effectivement l'exemple choisit pour comparaison n'a pas de réel
intérêt : dans les deux cas il y a du procédural. De plus pour mesurer
l'intérêt de la chose il faut comparer avec plus ou moins de volume :
1) 500 lignes
2) 5 000 lignes
3) 50 000 lignes
4) 500 000 lignes
5) 5 000 000 lignes
en faisant en sorte que le volume dépasse la RAM disponible pour voir
quels sont les effets du cache de données.
A +"Patrice" a écrit dans le message de news:
eG1Pwy$%Ce traitement peut-il être mis sous forme ensembliste (par exemple CASE)
?
Si on est *obligé* de parcourir séquentiellement les lignes d'une table,
le
curseur sera plus rapide qu'un parcours simulé à base de boucles et
d'instructions SQL...
Donc le cas d'école que tu as plus haut, tu peux te passer d'une boucle,
la
vraie comparaison serait donc plutôt avec un simple
UPDATE MaTable SET UneColonne=MonRésultat
Disons que pour être plus précis, la recommandation que voulait
transmettre
le formateur est de choisir toujours un traitement "ensembliste" par
rapport
à un parcours séquentiel explicite des données (et dans ce cas un CURSOR
peut être la meilleure solution).
--
Patrice
"MB" a écrit dans le message de
news:OzJYvU$%Pour vous répondre, dans la boucle il y a gros traitement sur du contôle
dedonnées avec beaucoup if if if if ....
Pour le test, nous avons dans un premier temps supprimé tous les if if
if
if .... et comparé que les boucles sur le jeu de données avec et sans
curseur. C'est le curseur le plus rapide avec 1 minute de moins sur 8000
enregistrements.
"Patrice" a écrit dans le message de news:
%23dzFYb%23%Tu veux dire sans doute bannir les "curseurs" et non pas les
"procédures
stockées" ?
Ta procédure stockée fait également un traitement procédural ce qui est
sans
doute le problème. Ce n'est pas à proprement parler les "curseurs" qui
sont
à "éviter" mais plutôt le traitement "procédural" par opposition aux
traitements ensemblistes...
Quel est ce fameux traitement ? N'est il pas réalisable avec une
instruction
SQL unique... Pour l'instant à part le flag et le comptage je ne vois
pastrop ce que tu cherches à faire...
Après il y a des cas où tu es sans doute obligé...
--
Patrice
"MB" a écrit dans le message de
news:e8NlcD%23%Bonjour
Je sort d'une formation et le discours était
Bannir les procèdures stokées
Bannir les select *
Nous n'avons pas encore poussé nos tests très loin mais pour l'instant
les
curseurs vont plus vite et les select * aussi !
voilà la méthode que l'on a utilisé
- voici un lien qui vous dira comment éviter les curseurs:
http://sqlpro.developpez.com/cours/sqlserver/MSSQLServer_avoidCursor/
et voilà note test
Avec curseur
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_NOM_IDE nvarchar(150)
DECLARE @nvc_PAT_NOM_JF nvarchar(150)
DECLARE @nvc_DEBUT_NOM nvarchar(10)
DECLARE @int_PAT_SEXE int
DECLARE @int_PAT_NAI_JJ int
DECLARE @int_PAT_NAI_MM int
DECLARE @int_PAT_NAI_AA int
DECLARE @int_IDE_CLE int
DECLARE @nvc_USG_CLE nvarchar(150)
DECLARE @cpt int--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE
END
SET @cpt = 0--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- Ouverture du curseur de parcours des enregistrements
DECLARE cur_CleIdentite CURSOR
FOR
SELECT
CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE
OPEN cur_CleIdentite
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
WHILE @@FETCH_STATUS = 0
begin
--- ***************************************************
--- Corps du programme
SET @cpt = @cpt + 1
--- ********************************************************
FETCH NEXT FROM cur_CleIdentite
INTO @int_IDE_CLE
End
--- fermeture du curseur
Close cur_CleIdentite
DEALLOCATE cur_CleIdentite
print @cpt
___________________________________________________________________________________________SANS CURSOR
DECLARE @nvc_PRE_IDE nvarchar(150)
DECLARE @nvc_PRE_IDE nvarchar(150);
DECLARE @nvc_NOM_IDE nvarchar(150);
DECLARE @nvc_PAT_NOM_JF nvarchar(150);
DECLARE @nvc_DEBUT_NOM nvarchar(10);
DECLARE @int_PAT_SEXE int;
DECLARE @int_PAT_NAI_JJ int;
DECLARE @int_PAT_NAI_MM int;
DECLARE @int_PAT_NAI_AA int;
DECLARE @int_IDE_CLE int;
DECLARE @cpt int;--- ---------------------------------------------------------------------
---------------------------------------- On efface les anciens enregistrements de la base
DELETE FROM TMP_TAB_REC_DOUBLONS_DS_BASE
WHERE USG_CLE = @nvc_USG_CLE;
SELECT
@cpt = count(*)
FROM TMP_TAB_REC_DOUBLONS_DS_BASE;
IF @cpt = 0
BEGIN
TRUNCATE TABLE TMP_TAB_REC_DOUBLONS_DS_BASE;
END;
SET @cpt = 0;--- ---------------------------------------------------------------------
---------------------------------------- ---------------------------------------------------------------------
---------------------------------------- On stocke les clé des identités dans une table temporaire
SELECT
CLE_IDE,
0 AS OK
INTO #TMP_CLE_IDE
FROM ADR_TAB_IDENTITES
ORDER BY CLE_IDE;
-- tant qu'il y a au moins une table à traiter
WHILE EXISTS(
SELECT
CLE_IDE
FROM #TMP_CLE_IDE
WHERE OK = 0)
BEGIN
-- prendre la clé de la première identité à traiter
SET @int_IDE_CLE = ( SELECT TOP 1 CLE_IDE
FROM #TMP_CLE_IDE WHERE OK = 0
ORDER BY 1);
---
********************************************************************
--- Corps du programme
SET @cpt = @cpt + 1
---
********************************************************************
-- flaguer l'objet traité dans la table des objets à traiter
UPDATE #TMP_CLE_IDE
SET OK = 1
WHERE CLE_IDE = @int_IDE_CLE;
--- Fin de la boucle WHILE
END;
-- supprimez la table temporaire de traitement
DROP TABLE #TMP_CLE_IDE;
print @cpt
voilou
--
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 ***********************