Bonjour,
Je suis novice sous sql server 2000 et j'aurai besoin d'aide pour l'optimisation de ma procédure stockée qui met plusieurs heures à s exécuter.
Je reçois mensuellement un fichier csv (20 million de lignes) contenant les soldes des contrats par mois. les champs sont séparés par des ';' et sont délimités par des doubles cotes.
Voici la procédure que j'ai créé et qui mérite d'être largement optimisé.
- J’insère via un bulk insert les données dans une table source
- je met à jour les 1er et le dernier champ de la table en supprimant les doubles cotes.
- J’insère les nouveaux contrats dans la tables de destination
- j'identifie sur quel mois porte les soldes (forcément 1 pas plus)
- Je mets à jour la colonne mois avec les soldes du fichier source.
Script table source et destination
Script proc
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TBL_CONTRAT]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[TBL_CONTRAT] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TBL_SOURCE_PPH]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[TBL_SOURCE_PPH] GO CREATE TABLE [dbo].[TBL_CONTRAT] ( [Num_contrat] [bigint] NOT NULL , [CD_type_titulaire] [tinyint] NOT NULL , [Date_naissance] [datetime] NULL , [num_type_contrat] [tinyint] NOT NULL , [Date_ouverture] [datetime] NULL , [Date_fermeture] [datetime] NULL , [Departement] [varchar] (5) COLLATE French_CI_AS NULL , [janvier] [money] NULL , [février] [money] NULL , [mars] [money] NULL , [avril] [money] NULL , [mai] [money] NULL , [juin] [money] NULL , [juillet] [money] NULL , [août] [money] NULL , [septembre] [money] NULL , [octobre] [money] NULL , [novembre] [money] NULL , [décembre] [money] NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[TBL_SOURCE_PPH] ( [NO_CNT_DET] [varchar] (50) COLLATE French_CI_AS NOT NULL , [CD_TYP_TTL] [varchar] (50) COLLATE French_CI_AS NULL , [DT_NAI] [nvarchar] (50) COLLATE French_CI_AS NULL , [CD_CNT_TYP] [varchar] (50) COLLATE French_CI_AS NULL , [LB_CNT_TYP] [varchar] (50) COLLATE French_CI_AS NULL , [Département] [varchar] (50) COLLATE French_CI_AS NULL , [DT_EFF_CNT] [nvarchar] (50) COLLATE French_CI_AS NULL , [DT_CLO_CNT] [nvarchar] (50) COLLATE French_CI_AS NULL , [DT_SLD] [nvarchar] (50) COLLATE French_CI_AS NULL , [CPL_PRD_EPA_ORD] [varchar] (50) COLLATE French_CI_AS NULL ) ON [PRIMARY] GO
Pour finir j'ai créé des index sur les champs num_contrat, CD_type_titulaire, Date_naissance.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 CREATE PROCEDURE SP_IMPORT_OER @PathFileName varchar(100) as DECLARE @SQL varchar(2000), @Mois_source as varchar(30), @req2 as varchar(2000) truncate table dbo.TBL_SOURCE_PPH set @SQL = 'BULK INSERT TBL_SOURCE_PPH FROM "'+@PathFileName+'" WITH (FIELDTERMINATOR =''";"'' , FIRSTROW = 2)' EXEC (@SQL) update tbl_source set NO_CNT_DET = replace(NO_CNT_DET,'"',''), CPL_PRD_EPA_ORD = replace(CPL_PRD_EPA_ORD,'"','') INSERT TBL_CONTRAT (Num_contrat, CD_type_titulaire, Date_naissance, num_type_contrat, Date_ouverture, Date_fermeture, Departement) SELECT cast(NO_CNT_DET as bigint), cast(a.CD_TYP_TTL as tinyint), case when isdate(a.DT_NAI)= 1 then cast(a.dt_nai as datetime) else null end as date_naiss, cast(a.CD_CNT_TYP as tinyint), case when isdate(a.DT_EFF_CNT)= 1 then cast(a.DT_EFF_CNT as datetime) else null end as date_EFF, case when isdate(a.DT_CLO_CNT)= 1 then cast(a.DT_CLO_CNT as datetime) else null end as date_CLO, [Département] from dbo.TBL_SOURCE_PPH as a where not exists (select * from dbo.TBL_CONTRAT as b where cast(a.NO_CNT_DET as bigint) = b.Num_contrat) -- Permet d'identifier la colonne de la table final set @Mois_source =(SELECT top 1 datename(M,DT_SLD) from dbo.TBL_SOURCE_PPH) set @req2='update dbo.TBL_CONTRAT set ' + @Mois_source + ' = cast(CPL_PRD_EPA_ORD as money) FROM dbo.TBL_CONTRAT inner join dbo.TBL_SOURCE_PPH on Num_contrat = cast(NO_CNT_DET as bigint)' exec(@req2) GO
La proc ne fonctionne pas en l'état il a fallut pour la faire fonctionner (en 20h) inserer des commandes dbcc shrinkdatase tempdb pour que les journaux de transactions n'explose pas.
Merci de bien vouloir m'indiquer quels sont les optimisations que je peux apporter à ma base et/ou mon script
Merci à tous et j’espère d'avoir été clair.
Partager