Problemas de rendimiento de SQL Server con 500.000 Mil registros.

05/05/2005 - 16:48 por Nicola Strappazzon | Informe spam
Hola muchachos, tengo un problema de rendimiento con SQL Server 2000 con
SP3a, resulta que estoy migrando 498.542 mil registros de un archivo plano
que fue exportado por un sistema de Natural /Adabas, a una sola tabla
temporal, y luego leo esos registros por medio de cursores para realizar una
normalización sencilla de esos datos e introducirlos a una tabla definitiva,
el caso es, que se tarda como 2:30 en un Pentium IV de 1.5 con 512 Mb de
RAM, para poder solamente migrar un aproximado de 100.000 mil registros. Esa
situación es normal por la cantidad de registros o se puede mejorar sin
poner mas hierro a la estación de trabajo (Uso Windows XP con SP2).



Estado del servidor mientras se ejecuta la consulta:

CPU: 80% ~100% de uso

Average del disco: no excede de un 8% de uso.

Memoria dinámica igual que el average del disco.

Tamaño de la memoria dinámica, 204 / 1024 Mb.



Aquí les pongo los 2 Stored Procedure para realizar esta operación.



Stored Procedure1:



SET NOCOUNT ON

DECLARE @Linea VARCHAR(35)
DECLARE @Cedula VARCHAR(8)
DECLARE @Cod_Materia VARCHAR(8)
DECLARE @Periodo TINYINT
DECLARE @Calificacion TINYINT
DECLARE @Estado TINYINT
DECLARE @ContSeparador TINYINT

CREATE TABLE #tbl_TempFile (Line VARCHAR(35))
EXEC ('BULK INSERT #tbl_TempFile FROM "D:\My Documents\Visual Studio
Projects\Applications\SAVA2.0\Datos de prueba\Record Academico.TXT"')

DECLARE TempCursor CURSOR FOR SELECT Line FROM #tbl_TempFile
OPEN TempCursor
FETCH NEXT FROM TempCursor INTO @Linea
WHILE (@@FETCH_STATUS <> -1)
BEGIN
SET @ContSeparador = 0
WHILE (@ContSeparador <= 4)
BEGIN
IF(@ContSeparador = 0)
SET @Cedula = SUBSTRING(@Linea,1,CHARINDEX('|',@Linea)-1)
ELSE IF(@ContSeparador = 1)
SET @Cod_Materia = LTRIM(SUBSTRING(@Linea,1,CHARINDEX('|',@Linea)-1))
ELSE IF(@ContSeparador = 2)
SET @Periodo = SUBSTRING(@Linea,1,CHARINDEX('|',@Linea)-1)
ELSE IF(@ContSeparador = 3)
SET @Calificacion = SUBSTRING(@Linea,1,CHARINDEX('|',@Linea)-1)
ELSE IF(@ContSeparador = 4)
SET @Estado = @Linea
SET @Linea = SUBSTRING(@Linea,CHARINDEX('|',@Linea)+1, LEN(@Linea))
SET @ContSeparador = @ContSeparador + 1
END
EXEC SP_IMPORTAR_Calificaciones @Cedula, @Periodo, @Cod_Materia,
@Calificacion, @Estado
FETCH NEXT FROM TempCursor INTO @Linea
END
CLOSE TempCursor
DEALLOCATE TempCursor
DROP TABLE #tbl_TempFile



Stored Procedure 2. que es llamada por la Stored Procedure1.



SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

ALTER PROCEDURE [SP_IMPORTAR_Calificaciones]
(@PK_Estudiante [int],
@FK_Periodo [int],
@Asignatura [varchar] (8),
@Calificacion [tinyint],
@FK_MateriaEstado [tinyint])
AS

SET NOCOUNT ON

DECLARE @Pensum INT
DECLARE @Escuela INT
DECLARE @Semestre INT
DECLARE @Ordinal INT
DECLARE @TEMP_Asignatura INT

SET @Pensum = SUBSTRING(@Asignatura, 1, 2)
SET @Escuela = SUBSTRING(@Asignatura, 3, 2)
SET @Semestre = SUBSTRING(@Asignatura, 5, 2)
SET @Ordinal = SUBSTRING(@Asignatura, 7, 2)

SET @TEMP_Asignatura = (SELECT PK_Asignatura
FROM dbo.tbl_Asignaturas
WHERE FK_Pensum = @Pensum AND
FK_Escuela = @Escuela AND
FK_Semestre = @Semestre AND
Ordinal = @Ordinal)

IF (EXISTS (SELECT PK_Persona FROM tbl_Personas WHERE PK_Persona =
@PK_Estudiante))
BEGIN
IF (NOT EXISTS (SELECT FK_Asignatura
FROM tbl_MateriasInscritas
WHERE FK_Estudiante = @PK_Estudiante AND
FK_Asignatura = @TEMP_Asignatura AND
FK_Periodo = @FK_Periodo AND
FK_MateriaEstado = @FK_MateriaEstado AND
Calificacion = @Calificacion))
BEGIN
INSERT INTO tbl_MateriasInscritas(
FK_Estudiante,
FK_Asignatura,
FK_Periodo,
FK_MateriaEstado,
Calificacion)
VALUES(
@PK_Estudiante,
@TEMP_Asignatura,
@FK_Periodo,
@FK_MateriaEstado,
@Calificacion)
RETURN 1
END
ELSE
BEGIN
RETURN -3
END
END
ELSE
BEGIN
RETURN -4
END



GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
 

Leer las respuestas

#1 Alejandro Mesa
05/05/2005 - 17:31 | Informe spam
Nicola,

temporal, y luego leo esos registros por medio de cursores para realizar una



Ahi esta el problema. SQL Server esta diseñado para trbajar con conjuntos y
no fila a fila que es lo que se esta haciendo al usar cursores. Trata de
buscar una solucion en base a conjuntos.


AMB

"Nicola Strappazzon" wrote:

Hola muchachos, tengo un problema de rendimiento con SQL Server 2000 con
SP3a, resulta que estoy migrando 498.542 mil registros de un archivo plano
que fue exportado por un sistema de Natural /Adabas, a una sola tabla
temporal, y luego leo esos registros por medio de cursores para realizar una
normalización sencilla de esos datos e introducirlos a una tabla definitiva,
el caso es, que se tarda como 2:30 en un Pentium IV de 1.5 con 512 Mb de
RAM, para poder solamente migrar un aproximado de 100.000 mil registros. Esa
situación es normal por la cantidad de registros o se puede mejorar sin
poner mas hierro a la estación de trabajo (Uso Windows XP con SP2).



Estado del servidor mientras se ejecuta la consulta:

CPU: 80% ~100% de uso

Average del disco: no excede de un 8% de uso.

Memoria dinámica igual que el average del disco.

Tamaño de la memoria dinámica, 204 / 1024 Mb.



Aquí les pongo los 2 Stored Procedure para realizar esta operación.



Stored Procedure1:



SET NOCOUNT ON

DECLARE @Linea VARCHAR(35)
DECLARE @Cedula VARCHAR(8)
DECLARE @Cod_Materia VARCHAR(8)
DECLARE @Periodo TINYINT
DECLARE @Calificacion TINYINT
DECLARE @Estado TINYINT
DECLARE @ContSeparador TINYINT

CREATE TABLE #tbl_TempFile (Line VARCHAR(35))
EXEC ('BULK INSERT #tbl_TempFile FROM "D:\My Documents\Visual Studio
Projects\Applications\SAVA2.0\Datos de prueba\Record Academico.TXT"')

DECLARE TempCursor CURSOR FOR SELECT Line FROM #tbl_TempFile
OPEN TempCursor
FETCH NEXT FROM TempCursor INTO @Linea
WHILE (@@FETCH_STATUS <> -1)
BEGIN
SET @ContSeparador = 0
WHILE (@ContSeparador <= 4)
BEGIN
IF(@ContSeparador = 0)
SET @Cedula = SUBSTRING(@Linea,1,CHARINDEX('|',@Linea)-1)
ELSE IF(@ContSeparador = 1)
SET @Cod_Materia = LTRIM(SUBSTRING(@Linea,1,CHARINDEX('|',@Linea)-1))
ELSE IF(@ContSeparador = 2)
SET @Periodo = SUBSTRING(@Linea,1,CHARINDEX('|',@Linea)-1)
ELSE IF(@ContSeparador = 3)
SET @Calificacion = SUBSTRING(@Linea,1,CHARINDEX('|',@Linea)-1)
ELSE IF(@ContSeparador = 4)
SET @Estado = @Linea
SET @Linea = SUBSTRING(@Linea,CHARINDEX('|',@Linea)+1, LEN(@Linea))
SET @ContSeparador = @ContSeparador + 1
END
EXEC SP_IMPORTAR_Calificaciones @Cedula, @Periodo, @Cod_Materia,
@Calificacion, @Estado
FETCH NEXT FROM TempCursor INTO @Linea
END
CLOSE TempCursor
DEALLOCATE TempCursor
DROP TABLE #tbl_TempFile



Stored Procedure 2. que es llamada por la Stored Procedure1.



SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

ALTER PROCEDURE [SP_IMPORTAR_Calificaciones]
(@PK_Estudiante [int],
@FK_Periodo [int],
@Asignatura [varchar] (8),
@Calificacion [tinyint],
@FK_MateriaEstado [tinyint])
AS

SET NOCOUNT ON

DECLARE @Pensum INT
DECLARE @Escuela INT
DECLARE @Semestre INT
DECLARE @Ordinal INT
DECLARE @TEMP_Asignatura INT

SET @Pensum = SUBSTRING(@Asignatura, 1, 2)
SET @Escuela = SUBSTRING(@Asignatura, 3, 2)
SET @Semestre = SUBSTRING(@Asignatura, 5, 2)
SET @Ordinal = SUBSTRING(@Asignatura, 7, 2)

SET @TEMP_Asignatura = (SELECT PK_Asignatura
FROM dbo.tbl_Asignaturas
WHERE FK_Pensum = @Pensum AND
FK_Escuela = @Escuela AND
FK_Semestre = @Semestre AND
Ordinal = @Ordinal)

IF (EXISTS (SELECT PK_Persona FROM tbl_Personas WHERE PK_Persona =
@PK_Estudiante))
BEGIN
IF (NOT EXISTS (SELECT FK_Asignatura
FROM tbl_MateriasInscritas
WHERE FK_Estudiante = @PK_Estudiante AND
FK_Asignatura = @TEMP_Asignatura AND
FK_Periodo = @FK_Periodo AND
FK_MateriaEstado = @FK_MateriaEstado AND
Calificacion = @Calificacion))
BEGIN
INSERT INTO tbl_MateriasInscritas(
FK_Estudiante,
FK_Asignatura,
FK_Periodo,
FK_MateriaEstado,
Calificacion)
VALUES(
@PK_Estudiante,
@TEMP_Asignatura,
@FK_Periodo,
@FK_MateriaEstado,
@Calificacion)
RETURN 1
END
ELSE
BEGIN
RETURN -3
END
END
ELSE
BEGIN
RETURN -4
END



GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO





Preguntas similares