Una tabla por cada año y UNION

09/10/2004 - 12:13 por Pedro Jose Caceres | Informe spam
Tengo una tabla de movimientos para cada año, MOV2003, MOV2004, etc.
Cuando se cierra un año por tanto, tengo que crear la nueva tabla
correspondiente al nuevo año. Puedo hacer el CREATE TABLE en t-sql sin
tener que sacar los usuarios del sistema ? Como puedo tomar la estructura de
otra de las tablas ya existentes para que se cree igual ?

Otra cosa es que para en una consulta ver movimientos que abarque dos o mas
años, hago una UNION, preparando dinamicamente la instruccion SELECT desde
la aplicacion y enviandola por odbc al servidor. Por ej. si la lista de
movimientos abarca va desde el 01/04/2001 al 31/03/2004, estoy armando desde
el front-end la union asi::


SELECT columna1, .., from MOV2001 WHERE ITEM='ELITEM' FECHA>/04/2001
UNION
SELECT columna1, .., from MOV2002 WHERE ITEM='ELITEM'
UNION
SELECT columna1, .., from MOV2003 WHERE ITEM='ELITEM'
UNION
SELECT columna1, .., from MOV2004 WHERE FECHA<1/03/2004
ORDER BY FECHA


Consideran que sea esta la mejor forma para hacer esto ?

De no ser, que otras opciones hay para extraer esta informacion quizas en un
SP del mismo servidor?

Gracias

Preguntas similare

Leer las respuestas

#16 Pedro Jose Caceres
11/10/2004 - 13:12 | Informe spam
Entonces ?

Me conviene o no el particionamiento ?




"SqlRanger" wrote in message
news:%
Eso depende del tipo de consultas que se hagan sobre la tabla. Si la tabla
sólo se consulta por la fecha y por la clave primaria completa, podrías
prescindir de particionar la tabla, teniendo un índice agrupado para la
fecha y un índice no agrupado para la clave primaria. Teniendo un índice
agrupado por la fecha, las consultas que tengan como criterio la fecha


verán
aumentado su rendimiento de forma espectacular.

Ten en cuenta además que el particionamiento de la tabla no sólo puede
aumentar el rendimiento de ciertas consultas, sino que también es
beneficioso para ciertas operaciones, como copias de seguridad de archivos


y
grupos de archivos, si cada tabla anual la pones en un archivo diferente,


no
tienes que hacer copias de seguridad periódicas de ellas, con tener una
copia es suficiente ya que no cambian los datos.

Saludos

Jesús López
MVP


"Pedro Jose Caceres" escribió en el mensaje
news:u3vOK$
> Ok... muy buena la discusión y se lo agradezco.
>
> Podemos concluir que para mi caso:
> Si tengo un indice por la fecha no tengo necesidad de tener las tablas
> particionadas por año por más grandes que éstas sean ???
> Díganme que si ! diganme que si!!! :))) seria un sueño para mi tener


una
> sola tabla para movimientos y que no me afecte el registro diario
intensivo
> de transacciones.
>
>
> Gracias
>
>
>
> "SqlRanger" wrote in message
> news:
> > Comentarios en línea,
> >
> > Saludos
> >
> > Jesús López
> > MVP
> >
> >
> > "Javier Loria" escribió en el mensaje
> > news:
> > > Hola:
> > > >Porque algunos dicen que es inversamente proporcional?
> > > No se, pero ese es un "Mito Urbano", probablemente


proveniente
de
> > SQL
> > > 6.5 o de otras plataformas.Disculpa lo largo del mensaje pero es


mejor
> que
> > > lo pruebes.
> > > El siguiente codigo te genera una tabla parecidas al esquema que
nos
> > > comentaste, la columna blanco es solo para simular otras columnas.
> > > TABLAS INDEPENDIENTES ==> > > > CREATE TABLE Mov2001(
> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
> > > , Fecha SMALLDATETIME NOT NULL
> > > , Nombre CHAR(20) NOT NULL
> > > , Blanco CHAR(100) DEFAULT('')
> > > )
> > >
> > > CREATE TABLE Mov2002(
> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
> > > , Fecha SMALLDATETIME NOT NULL
> > > , Nombre CHAR(20) NOT NULL
> > > , Blanco CHAR(100) DEFAULT('')
> > > )
> > >
> > > CREATE TABLE Mov2003(
> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
> > > , Fecha SMALLDATETIME NOT NULL
> > > , Nombre CHAR(20) NOT NULL
> > > , Blanco CHAR(100) DEFAULT('')
> > > )
> > > CREATE NONCLUSTERED INDEX IN_FechaMov2001
> > > ON Mov2001(Fecha)
> > > CREATE NONCLUSTERED INDEX IN_FechaMov2002
> > > ON Mov2002(Fecha)
> > > CREATE NONCLUSTERED INDEX IN_FechaMov2003
> > > ON Mov2003(Fecha)
> > > GO
> > >
> > > CREATE VIEW Movimientos AS
> > > SELECT * FROM Mov2001 -- Pendiente eliminar *'s
> > > UNION ALL
> > > SELECT * FROM Mov2002
> > > UNION ALL
> > > SELECT * FROM Mov2003
> > >
> > > FIN DE TABLAS INDEPENDIENTES ==> > > > Para simular la carga hice un script que genera n movimientos


diarios,
y
> > que
> > > probe con 400 diarios que son solo 146,000 filas anuales, pero que
bien
> > > podrias cambiar a 15000 filas diarias
> > > LLENADO DE TABLAS ==> > > > DECLARE @NumeroDiario INT
> > > SET @
> > >
> > > INSERT MOV2001(ID, Fecha, Nombre)
> > > SELECT ((N1.Numero-1)*@NumeroDiario)+N2.Numero
> > > , DATEADD(dd,N1.Numero-1,'2001/01/01')
> > > , CONVERT(CHAR(10),DATEADD(dd,N1.Numero-1,'2001/01/01'),112)
> > > + RIGHT(' '
> > > +CAST(((N1.Numero-1)*@NumeroDiario)+N2.Numero AS VARCHAR(7)),7)
> > > FROM Numeros AS N1
> > > CROSS JOIN Numeros AS N2
> > > WHERE N1.Numero<366
> > > AND N2.Numero<=@NumeroDiario
> > >
> > > INSERT Mov2002(ID, Fecha, Nombre)
> > > SELECT Id+@NumeroDiario*365 , DATEADD(year, 1, Fecha)
> > > , Nombre
> > > FROM Mov2001
> > >
> > > INSERT Mov2003(ID, Fecha, Nombre)
> > > SELECT Id+@NumeroDiario*365*2
> > > , DATEADD(year, 1, Fecha)
> > > , Nombre
> > > FROM Mov2002
> > > GO
> > >
> > > FIN DE LLENADO DE TABLAS ==> > > > La consulta usa una tabla de numeros muy sencilla con una unica
> > columna
> > > que tiene los numeros del 1 en adelante, en tu caso deberia ser por


lo
> > menos
> > > hasta 15000.
> > > Los resultados son:
> > > ==> > > > SELECT * FROM Mov2003 WHERE Fecha='2003-07-01'
0,
> > > read-ahead reads 0.
> > > ==> > > > SELECT * FROM Movimientos WHERE Fecha='2003-07-01'


0,
> > > read-ahead reads 0.
> > > read-ahead reads 0.
> > > read-ahead reads 0.
> > > ==> > > > La diferencia entre usar la vista y la tabla es casi nula (solo
lee
> el
> > > encabezado del indice y la descarta). No hay cambios en el desempeno
> > > importantes por usar una u otra.
> >
> > Si hubiéramos puesto una restricción CHECK en las tablas que asegurara
que
> > la fecha sólo puede ser del año correspondiente SQL Server no habría
> tenido
> > que ir al índice a comprobarlo y la diferencia entre tabla y vista
habría
> > sido completamente nula.
> >
> >
> >
> > > Si borras todo y creas una unica tabla de movimientos:
> > > TABLA UNICA ==> > > > CREATE TABLE Movimientos(
> > > Id INT NOT NULL
> > > PRIMARY KEY CLUSTERED
> > > , Fecha SMALLDATETIME NOT NULL
> > > , Nombre CHAR(20) NOT NULL
> > > , Blanco CHAR(100) DEFAULT('')
> > > )
> > >
> > > == FIN DE TABLA UNICA ==> > > > CREATE NONCLUSTERED INDEX IN_FechaMovimientos
> > > ON Movimientos(Fecha)
> > >
> > > DECLARE @NumeroDiario INT
> > > SET @
> > >
> > > INSERT MOVIMIENTOS(ID, Fecha, Nombre)
> > > SELECT ((N1.Numero-1)*@NumeroDiario)+N2.Numero AS Numero
> > > ,DATEADD(dd,N1.Numero-1,'2001/01/01') AS Fecha
> > > , CONVERT(CHAR(10),DATEADD(dd,N1.Numero-1,'2001/01/01'),112)
> > > + RIGHT(' '
+CAST(((N1.Numero-1)*@NumeroDiario)+N2.Numero
> AS
> > > VARCHAR(7)),7) as Nombre
> > > FROM Numeros AS N1
> > > CROSS JOIN Numeros AS N2
> > > WHERE N1.Numero<366
> > > AND N2.Numero<=@NumeroDiario
> > >
> > > INSERT Movimientos(ID, Fecha, Nombre)
> > > SELECT Id+@NumeroDiario*365
> > > , DATEADD(year, 1, Fecha)
> > > , Nombre
> > > FROM Movimientos
> > > UNION ALL
> > > SELECT Id+@NumeroDiario*365*2
> > > , DATEADD(year, 1, Fecha)
> > > , Nombre
> > > FROM Mov2002
> > > GO
> > > SELECT * FROM Movimientos WHERE Fecha='2003-07-01'
> > >
0,
> > > read-ahead reads 0.
> > > ==> > >
> > Creo que aquí hay un error. La tabla es Movimientos, no Mov2003. El
número
> > de logical reads debería haber sido el triple. Ya que la consulta hace
una
> > exploración completa de la tabla (no usa el índice de la fecha) y la
tabla
> > es tres veces más grande.
> >
> > > Veras que la consulta es exactamente igual que si usaras cada
tabla
> > por
> > > separado. La estructura de indices de SQL hace que normalmente sea


mas
> > > eficiente tener una sola tabla a n tablas iguales EXCEPTO cuando


cada
> una
> > de
> > > las tabla va a un disco independiente. En cuyo caso la vista es lo
> > > recomendable.
> >
> >
> > No estoy de acuerdo.Creo que has cometido algún error en las pruebas.
> >
> > Para el caso de la consulta que estamos evaluando,. Será más eficiente
(el
> > número de tablas más eficiente) particionar la tabla cuando el índice
> sobre
> > la Fecha es un índice no agrupado y la consulta devuelve un número de
> > registros lo suficientemente grande como para que SQL Server determine
que
> > es mejor una exploración de la tabla que usar el índice. La razón es
> simple,
> > SQL Server sólo tendrá que hacer la exploración completa de una de las
> > tablas, las otras tablas no las mirará ya que hay una restricción


CHECK
> que
> > se lo indica.
> >
> > Si el índice sobre la columna Fecha es agrupado, la diferencia entre
> > particionar la tabla y no particionarala sería mínima, como mucho,
habría
> > una diferencia de una lectura lógica más con tabla única. Me estoy
> > refiriendo, por supuesto, a consultas en las que se obtienen todos las
> > columnas y en la cláusula where está la columna de partición.
> >
> > > Es posible definir un JOB anual que agregue una tabla y


modifique
la
> > > vista actual si se requiere.
> > >
> > >
> > > Javier Loria
> > > Costa Rica
> > > Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> > > que pueda ser copiado y pegado al Query Analizer.
> > > La version de SQL y Service Pack tambien ayuda
> > >
> > > "Pedro Jose Caceres" wrote in message
> > > news:
> > > > > Hola:
> > > > > El problema de esas tabla es que producen una perdida de
> desempeno
> > > > > importante, asi que considera la posiblidad de unirlas en una


sola
> > > tabla,
> > > > >
> > > >
> > > > Muchas gracias por la respuesta. Pero
> > > > Ok.. entonces por qué algunos dicen que el tamaño de las tablas es
> > > > inversamente proporcional al buen desempeño ?
> > > > A saber, son tablas de varios millones de registros (entre 4 y 5
> > millones)
> > > y
> > > > son de operaciones diarias de uso intensivo y lo de la separacion
> viene
> > > > porque los nuevos registros son casi invariablemente de fecha del
año
> > > > actual, por tanto las demas no se utilizan a menos que sea en
reportes
> y
> > > > consultas historicas.
> > > > Como le dije a Miguel arriba, la razon de partirlas fue


basicamente
> > > buscando
> > > > mayor eficiencia en el registro diario de operaciones y creo que


lei
> por
> > > ahi
> > > > que esa era una forma de eficientizarlo.
> > > > La verdad que a veces uno leyendo tantas opiniones distintas no


sabe
> por
> > > > donde irse. :)
> > > >
> > > > >a
> > > > > menos que cada una de ellas tenga su propio disco duro o


arreglo
de
> > > > discos.
> > > > > Adicionalmente si no quieres fusionarlas lo mejor seria,
usando
> la
> > > > > recomendacion de Miguel, crear una vista del tipo:
> > > > > > > > > > > CREATE VIEW Movimientos(Columna1, )
> > > > > FROM
> > > > > SELECT Columna1, Columna2 FROM Mov2001
> > > > > UNION ALL -- *** ALL es muy importante
> > > > > SELECT Columna1, Columna2 FROM Mov2002
> > > > > UNION ALL
> > > > >
> > > >
> > > >
> > > > El problema es que la cerrar cada año, como dije arriba hay que
crear
> > una
> > > > nueva tabla MovAAAA entonces implicaria modificar la vista ? esto
se
> > > podria
> > > > hacer en t-sql tambien ?
> > > >
> > > >
> > > > > > > > > > > Luego podras hacer un SELECT:
> > > > > > > > > > > SELECT Columna1, ... FROM Movimientos
> > > > > WHERE ITEM='xyz' FECHA>='01/04/2001'
> > > > > > > > > > > Que sera muy rapido, porque por las estadisticas de SQL el
sabra
> > que
> > > > > ninguna de las tablas, excepto la de Mov2004 tiene datos que
cumplan
> > la
> > > > > condicion de las fechas..
> > > > > Saludos,
> > > > >
> > > > >
> > > > > Javier Loria
> > > > > Costa Rica
> > > > > Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> > > > > que pueda ser copiado y pegado al Query Analizer.
> > > > > La version de SQL y Service Pack tambien ayuda
> > > > >
> > > > > "Pedro Jose Caceres" wrote in


message
> > > > > news:#
> > > > > > Tengo una tabla de movimientos para cada año, MOV2003,


MOV2004,
> > etc.
> > > > > > Cuando se cierra un año por tanto, tengo que crear la nueva
tabla
> > > > > > correspondiente al nuevo año. Puedo hacer el CREATE TABLE en
> t-sql
> > > sin
> > > > > > tener que sacar los usuarios del sistema ? Como puedo tomar la
> > > > estructura
> > > > > de
> > > > > > otra de las tablas ya existentes para que se cree igual ?
> > > > > >
> > > > > > Otra cosa es que para en una consulta ver movimientos que
abarque
> > dos
> > > o
> > > > > mas
> > > > > > años, hago una UNION, preparando dinamicamente la instruccion
> > SELECT
> > > > > desde
> > > > > > la aplicacion y enviandola por odbc al servidor. Por ej. si la
> lista
> > > de
> > > > > > movimientos abarca va desde el 01/04/2001 al 31/03/2004, estoy
> > armando
> > > > > desde
> > > > > > el front-end la union asi::
> > > > > >
> > > > > >
> > > > > > SELECT columna1, .., from MOV2001 WHERE ITEM='ELITEM'
> > > > FECHA>/04/2001
> > > > > > UNION
> > > > > > SELECT columna1, .., from MOV2002 WHERE ITEM='ELITEM'
> > > > > > UNION
> > > > > > SELECT columna1, .., from MOV2003 WHERE ITEM='ELITEM'
> > > > > > UNION
> > > > > > SELECT columna1, .., from MOV2004 WHERE FECHA<1/03/2004
> > > > > > ORDER BY FECHA
> > > > > >
> > > > > >
> > > > > > Consideran que sea esta la mejor forma para hacer esto ?
> > > > > >
> > > > > > De no ser, que otras opciones hay para extraer esta


informacion
> > quizas
> > > > en
> > > > > un
> > > > > > SP del mismo servidor?
> > > > > >
> > > > > > Gracias
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>


Respuesta Responder a este mensaje
#17 Pedro Jose Caceres
11/10/2004 - 13:17 | Informe spam
Uyyy me confundo un poco.

Segun los detalles que he citado, piensan que me conviene o no me conviene
tener la tabla de movimientos particionada por año ?




"Miguel Egea" wrote in message
news:%
Explicandome mejor, creo que todos pensamos lo mismo y que no se entiende
eso de nuestros mensajes.


"Miguel Egea" escribió en el mensaje
news:
> Jesús, no estoy de acuerdo en lo que se puede sobreentender de lo que
> dices.
>
> El resumen es que si SQL no necesita hacer un tableScan en ninguna
> consulta no se ve perjudicado, es decir si la indexación (ya sea


clustered
> o no clustered) es adecuada es muy probable que de exactamente igual que
> estén particionadas como juntas.
>
>
> -
> Miguel Egea Gómez
> Microsoft SQL-Server MVP
> Webmaster de PortalSql.Com
> ¿Te interesa participar en las reuniones
> del grupo de Usuarios de SQL-Server y .NET
> Se harán en levante de España, (Alicante o Murcia)?
>
>
> "SqlRanger" escribió en el mensaje
> news:%
>> Eso depende del tipo de consultas que se hagan sobre la tabla. Si la
>> tabla
>> sólo se consulta por la fecha y por la clave primaria completa, podrías
>> prescindir de particionar la tabla, teniendo un índice agrupado para la
>> fecha y un índice no agrupado para la clave primaria. Teniendo un


índice
>> agrupado por la fecha, las consultas que tengan como criterio la fecha
>> verán
>> aumentado su rendimiento de forma espectacular.
>>
>> Ten en cuenta además que el particionamiento de la tabla no sólo puede
>> aumentar el rendimiento de ciertas consultas, sino que también es
>> beneficioso para ciertas operaciones, como copias de seguridad de
>> archivos y
>> grupos de archivos, si cada tabla anual la pones en un archivo


diferente,
>> no
>> tienes que hacer copias de seguridad periódicas de ellas, con tener una
>> copia es suficiente ya que no cambian los datos.
>>
>> Saludos
>>
>> Jesús López
>> MVP
>>
>>
>> "Pedro Jose Caceres" escribió en el


mensaje
>> news:u3vOK$
>>> Ok... muy buena la discusión y se lo agradezco.
>>>
>>> Podemos concluir que para mi caso:
>>> Si tengo un indice por la fecha no tengo necesidad de tener las


tablas
>>> particionadas por año por más grandes que éstas sean ???
>>> Díganme que si ! diganme que si!!! :))) seria un sueño para mi tener
>>> una
>>> sola tabla para movimientos y que no me afecte el registro diario
>> intensivo
>>> de transacciones.
>>>
>>>
>>> Gracias
>>>
>>>
>>>
>>> "SqlRanger" wrote in message
>>> news:
>>> > Comentarios en línea,
>>> >
>>> > Saludos
>>> >
>>> > Jesús López
>>> > MVP
>>> >
>>> >
>>> > "Javier Loria" escribió en el mensaje
>>> > news:
>>> > > Hola:
>>> > > >Porque algunos dicen que es inversamente proporcional?
>>> > > No se, pero ese es un "Mito Urbano", probablemente
>>> > > proveniente
>> de
>>> > SQL
>>> > > 6.5 o de otras plataformas.Disculpa lo largo del mensaje pero es
>>> > > mejor
>>> que
>>> > > lo pruebes.
>>> > > El siguiente codigo te genera una tabla parecidas al esquema


que
>> nos
>>> > > comentaste, la columna blanco es solo para simular otras columnas.
>>> > > TABLAS INDEPENDIENTES ==> >>> > > CREATE TABLE Mov2001(
>>> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
>>> > > , Fecha SMALLDATETIME NOT NULL
>>> > > , Nombre CHAR(20) NOT NULL
>>> > > , Blanco CHAR(100) DEFAULT('')
>>> > > )
>>> > >
>>> > > CREATE TABLE Mov2002(
>>> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
>>> > > , Fecha SMALLDATETIME NOT NULL
>>> > > , Nombre CHAR(20) NOT NULL
>>> > > , Blanco CHAR(100) DEFAULT('')
>>> > > )
>>> > >
>>> > > CREATE TABLE Mov2003(
>>> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
>>> > > , Fecha SMALLDATETIME NOT NULL
>>> > > , Nombre CHAR(20) NOT NULL
>>> > > , Blanco CHAR(100) DEFAULT('')
>>> > > )
>>> > > CREATE NONCLUSTERED INDEX IN_FechaMov2001
>>> > > ON Mov2001(Fecha)
>>> > > CREATE NONCLUSTERED INDEX IN_FechaMov2002
>>> > > ON Mov2002(Fecha)
>>> > > CREATE NONCLUSTERED INDEX IN_FechaMov2003
>>> > > ON Mov2003(Fecha)
>>> > > GO
>>> > >
>>> > > CREATE VIEW Movimientos AS
>>> > > SELECT * FROM Mov2001 -- Pendiente eliminar *'s
>>> > > UNION ALL
>>> > > SELECT * FROM Mov2002
>>> > > UNION ALL
>>> > > SELECT * FROM Mov2003
>>> > >
>>> > > FIN DE TABLAS INDEPENDIENTES ==> >>> > > Para simular la carga hice un script que genera n movimientos
>>> > > diarios,
>> y
>>> > que
>>> > > probe con 400 diarios que son solo 146,000 filas anuales, pero


que
>> bien
>>> > > podrias cambiar a 15000 filas diarias
>>> > > LLENADO DE TABLAS ==> >>> > > DECLARE @NumeroDiario INT
>>> > > SET @
>>> > >
>>> > > INSERT MOV2001(ID, Fecha, Nombre)
>>> > > SELECT ((N1.Numero-1)*@NumeroDiario)+N2.Numero
>>> > > , DATEADD(dd,N1.Numero-1,'2001/01/01')
>>> > > , CONVERT(CHAR(10),DATEADD(dd,N1.Numero-1,'2001/01/01'),112)
>>> > > + RIGHT(' '
>>> > > +CAST(((N1.Numero-1)*@NumeroDiario)+N2.Numero AS


VARCHAR(7)),7)
>>> > > FROM Numeros AS N1
>>> > > CROSS JOIN Numeros AS N2
>>> > > WHERE N1.Numero<366
>>> > > AND N2.Numero<=@NumeroDiario
>>> > >
>>> > > INSERT Mov2002(ID, Fecha, Nombre)
>>> > > SELECT Id+@NumeroDiario*365 , DATEADD(year, 1, Fecha)
>>> > > , Nombre
>>> > > FROM Mov2001
>>> > >
>>> > > INSERT Mov2003(ID, Fecha, Nombre)
>>> > > SELECT Id+@NumeroDiario*365*2
>>> > > , DATEADD(year, 1, Fecha)
>>> > > , Nombre
>>> > > FROM Mov2002
>>> > > GO
>>> > >
>>> > > FIN DE LLENADO DE TABLAS ==> >>> > > La consulta usa una tabla de numeros muy sencilla con una


unica
>>> > columna
>>> > > que tiene los numeros del 1 en adelante, en tu caso deberia ser


por
>>> > > lo
>>> > menos
>>> > > hasta 15000.
>>> > > Los resultados son:
>>> > > ==> >>> > > SELECT * FROM Mov2003 WHERE Fecha='2003-07-01'


reads
>> 0,
>>> > > read-ahead reads 0.
>>> > > ==> >>> > > SELECT * FROM Movimientos WHERE Fecha='2003-07-01'


reads
>>> > > 0,
>>> > > read-ahead reads 0.


0,
>>> > > read-ahead reads 0.


0,
>>> > > read-ahead reads 0.
>>> > > ==> >>> > > La diferencia entre usar la vista y la tabla es casi nula


(solo
>> lee
>>> el
>>> > > encabezado del indice y la descarta). No hay cambios en el


desempeno
>>> > > importantes por usar una u otra.
>>> >
>>> > Si hubiéramos puesto una restricción CHECK en las tablas que


asegurara
>> que
>>> > la fecha sólo puede ser del año correspondiente SQL Server no habría
>>> tenido
>>> > que ir al índice a comprobarlo y la diferencia entre tabla y vista
>> habría
>>> > sido completamente nula.
>>> >
>>> >
>>> >
>>> > > Si borras todo y creas una unica tabla de movimientos:
>>> > > TABLA UNICA ==> >>> > > CREATE TABLE Movimientos(
>>> > > Id INT NOT NULL
>>> > > PRIMARY KEY CLUSTERED
>>> > > , Fecha SMALLDATETIME NOT NULL
>>> > > , Nombre CHAR(20) NOT NULL
>>> > > , Blanco CHAR(100) DEFAULT('')
>>> > > )
>>> > >
>>> > > == FIN DE TABLA UNICA ==> >>> > > CREATE NONCLUSTERED INDEX IN_FechaMovimientos
>>> > > ON Movimientos(Fecha)
>>> > >
>>> > > DECLARE @NumeroDiario INT
>>> > > SET @
>>> > >
>>> > > INSERT MOVIMIENTOS(ID, Fecha, Nombre)
>>> > > SELECT ((N1.Numero-1)*@NumeroDiario)+N2.Numero AS Numero
>>> > > ,DATEADD(dd,N1.Numero-1,'2001/01/01') AS Fecha
>>> > > , CONVERT(CHAR(10),DATEADD(dd,N1.Numero-1,'2001/01/01'),112)
>>> > > + RIGHT(' '
>> +CAST(((N1.Numero-1)*@NumeroDiario)+N2.Numero
>>> AS
>>> > > VARCHAR(7)),7) as Nombre
>>> > > FROM Numeros AS N1
>>> > > CROSS JOIN Numeros AS N2
>>> > > WHERE N1.Numero<366
>>> > > AND N2.Numero<=@NumeroDiario
>>> > >
>>> > > INSERT Movimientos(ID, Fecha, Nombre)
>>> > > SELECT Id+@NumeroDiario*365
>>> > > , DATEADD(year, 1, Fecha)
>>> > > , Nombre
>>> > > FROM Movimientos
>>> > > UNION ALL
>>> > > SELECT Id+@NumeroDiario*365*2
>>> > > , DATEADD(year, 1, Fecha)
>>> > > , Nombre
>>> > > FROM Mov2002
>>> > > GO
>>> > > SELECT * FROM Movimientos WHERE Fecha='2003-07-01'
>>> > >


reads
>> 0,
>>> > > read-ahead reads 0.
>>> > > ==> >>> >
>>> > Creo que aquí hay un error. La tabla es Movimientos, no Mov2003. El
>> número
>>> > de logical reads debería haber sido el triple. Ya que la consulta


hace
>> una
>>> > exploración completa de la tabla (no usa el índice de la fecha) y la
>> tabla
>>> > es tres veces más grande.
>>> >
>>> > > Veras que la consulta es exactamente igual que si usaras cada
>> tabla
>>> > por
>>> > > separado. La estructura de indices de SQL hace que normalmente sea
>>> > > mas
>>> > > eficiente tener una sola tabla a n tablas iguales EXCEPTO cuando
>>> > > cada
>>> una
>>> > de
>>> > > las tabla va a un disco independiente. En cuyo caso la vista es lo
>>> > > recomendable.
>>> >
>>> >
>>> > No estoy de acuerdo.Creo que has cometido algún error en las


pruebas.
>>> >
>>> > Para el caso de la consulta que estamos evaluando,. Será más


eficiente
>> (el
>>> > número de tablas más eficiente) particionar la tabla cuando el


índice
>>> sobre
>>> > la Fecha es un índice no agrupado y la consulta devuelve un número


de
>>> > registros lo suficientemente grande como para que SQL Server


determine
>> que
>>> > es mejor una exploración de la tabla que usar el índice. La razón es
>>> simple,
>>> > SQL Server sólo tendrá que hacer la exploración completa de una de


las
>>> > tablas, las otras tablas no las mirará ya que hay una restricción
>>> > CHECK
>>> que
>>> > se lo indica.
>>> >
>>> > Si el índice sobre la columna Fecha es agrupado, la diferencia entre
>>> > particionar la tabla y no particionarala sería mínima, como mucho,
>> habría
>>> > una diferencia de una lectura lógica más con tabla única. Me estoy
>>> > refiriendo, por supuesto, a consultas en las que se obtienen todos


las
>>> > columnas y en la cláusula where está la columna de partición.
>>> >
>>> > > Es posible definir un JOB anual que agregue una tabla y
>>> > > modifique
>> la
>>> > > vista actual si se requiere.
>>> > >
>>> > >
>>> > > Javier Loria
>>> > > Costa Rica
>>> > > Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
>>> > > que pueda ser copiado y pegado al Query Analizer.
>>> > > La version de SQL y Service Pack tambien ayuda
>>> > >
>>> > > "Pedro Jose Caceres" wrote in message
>>> > > news:
>>> > > > > Hola:
>>> > > > > El problema de esas tabla es que producen una perdida de
>>> desempeno
>>> > > > > importante, asi que considera la posiblidad de unirlas en una
>>> > > > > sola
>>> > > tabla,
>>> > > > >
>>> > > >
>>> > > > Muchas gracias por la respuesta. Pero
>>> > > > Ok.. entonces por qué algunos dicen que el tamaño de las tablas


es
>>> > > > inversamente proporcional al buen desempeño ?
>>> > > > A saber, son tablas de varios millones de registros (entre 4 y 5
>>> > millones)
>>> > > y
>>> > > > son de operaciones diarias de uso intensivo y lo de la


separacion
>>> viene
>>> > > > porque los nuevos registros son casi invariablemente de fecha


del
>> año
>>> > > > actual, por tanto las demas no se utilizan a menos que sea en
>> reportes
>>> y
>>> > > > consultas historicas.
>>> > > > Como le dije a Miguel arriba, la razon de partirlas fue
>>> > > > basicamente
>>> > > buscando
>>> > > > mayor eficiencia en el registro diario de operaciones y creo que
>>> > > > lei
>>> por
>>> > > ahi
>>> > > > que esa era una forma de eficientizarlo.
>>> > > > La verdad que a veces uno leyendo tantas opiniones distintas no
>>> > > > sabe
>>> por
>>> > > > donde irse. :)
>>> > > >
>>> > > > >a
>>> > > > > menos que cada una de ellas tenga su propio disco duro o
>>> > > > > arreglo
>> de
>>> > > > discos.
>>> > > > > Adicionalmente si no quieres fusionarlas lo mejor seria,
>> usando
>>> la
>>> > > > > recomendacion de Miguel, crear una vista del tipo:
>>> > > > > > >>> > > > > CREATE VIEW Movimientos(Columna1, )
>>> > > > > FROM
>>> > > > > SELECT Columna1, Columna2 FROM Mov2001
>>> > > > > UNION ALL -- *** ALL es muy importante
>>> > > > > SELECT Columna1, Columna2 FROM Mov2002
>>> > > > > UNION ALL
>>> > > > >
>>> > > >
>>> > > >
>>> > > > El problema es que la cerrar cada año, como dije arriba hay que

>> crear
>>> > una
>>> > > > nueva tabla MovAAAA entonces implicaria modificar la vista ?


esto
>> se
>>> > > podria
>>> > > > hacer en t-sql tambien ?
>>> > > >
>>> > > >
>>> > > > > > >>> > > > > Luego podras hacer un SELECT:
>>> > > > > > >>> > > > > SELECT Columna1, ... FROM Movimientos
>>> > > > > WHERE ITEM='xyz' FECHA>='01/04/2001'
>>> > > > > > >>> > > > > Que sera muy rapido, porque por las estadisticas de SQL el
>> sabra
>>> > que
>>> > > > > ninguna de las tablas, excepto la de Mov2004 tiene datos que
>> cumplan
>>> > la
>>> > > > > condicion de las fechas..
>>> > > > > Saludos,
>>> > > > >
>>> > > > >
>>> > > > > Javier Loria
>>> > > > > Costa Rica
>>> > > > > Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
>>> > > > > que pueda ser copiado y pegado al Query Analizer.
>>> > > > > La version de SQL y Service Pack tambien ayuda
>>> > > > >
>>> > > > > "Pedro Jose Caceres" wrote in
>>> > > > > message
>>> > > > > news:#
>>> > > > > > Tengo una tabla de movimientos para cada año, MOV2003,
>>> > > > > > MOV2004,
>>> > etc.
>>> > > > > > Cuando se cierra un año por tanto, tengo que crear la nueva
>> tabla
>>> > > > > > correspondiente al nuevo año. Puedo hacer el CREATE TABLE


en
>>> t-sql
>>> > > sin
>>> > > > > > tener que sacar los usuarios del sistema ? Como puedo tomar


la
>>> > > > estructura
>>> > > > > de
>>> > > > > > otra de las tablas ya existentes para que se cree igual ?
>>> > > > > >
>>> > > > > > Otra cosa es que para en una consulta ver movimientos que
>> abarque
>>> > dos
>>> > > o
>>> > > > > mas
>>> > > > > > años, hago una UNION, preparando dinamicamente la


instruccion
>>> > SELECT
>>> > > > > desde
>>> > > > > > la aplicacion y enviandola por odbc al servidor. Por ej. si


la
>>> lista
>>> > > de
>>> > > > > > movimientos abarca va desde el 01/04/2001 al 31/03/2004,


estoy
>>> > armando
>>> > > > > desde
>>> > > > > > el front-end la union asi::
>>> > > > > >
>>> > > > > >
>>> > > > > > SELECT columna1, .., from MOV2001 WHERE ITEM='ELITEM'
>>> > > > FECHA>/04/2001
>>> > > > > > UNION
>>> > > > > > SELECT columna1, .., from MOV2002 WHERE ITEM='ELITEM'
>>> > > > > > UNION
>>> > > > > > SELECT columna1, .., from MOV2003 WHERE ITEM='ELITEM'
>>> > > > > > UNION
>>> > > > > > SELECT columna1, .., from MOV2004 WHERE FECHA<1/03/2004
>>> > > > > > ORDER BY FECHA
>>> > > > > >
>>> > > > > >
>>> > > > > > Consideran que sea esta la mejor forma para hacer esto ?
>>> > > > > >
>>> > > > > > De no ser, que otras opciones hay para extraer esta
>>> > > > > > informacion
>>> > quizas
>>> > > > en
>>> > > > > un
>>> > > > > > SP del mismo servidor?
>>> > > > > >
>>> > > > > > Gracias
>>> > > > > >
>>> > > > > >
>>> > > > >
>>> > > > >
>>> > > >
>>> > > >
>>> > >
>>> > >
>>> >
>>> >
>>>
>>>
>>
>>
>
>


Respuesta Responder a este mensaje
#18 SqlRanger
11/10/2004 - 14:12 | Informe spam
Entonces, dinos qué consultas se hacen sobre la tabla y te lo diremos.

Saludos,

Jesús López
MVP
Respuesta Responder a este mensaje
#19 SqlRanger
11/10/2004 - 14:29 | Informe spam
Pos eso. No líes al personal Miguelón.

En este caso particular, en el que se hace:

select * from LaTabla where fecha = UnaFecha

Como hay muchos registros para una fecha dada, un índice no agrupado sobre
la fecha no sirve para nada y se hace una exploración completa de la tabla.
Así que si tenemos la tabla particionada por fechas tendremos un aumento del
rendimiento igual al número de tablas porque sólo se recorría una de las
tablas, como dije en mi primer mensaje de este hilo.

Ahora en esta consulta, si el índice por fecha es agrupado, es una tontería
tener la tabla particionada por fechas ya que como mucho la diferencia entre
particionarla y no particionarla es de leer una página más, una nimiedad.
Además entonces esta consulta se ejecuta muy rápido.

Entonces todo parece claro. Ponemos un índice agrupado en la fecha y no
particionamos, ¿punto y final?. Pues no, qué pasa con las demás consultas
¿Qué otras consultas se hacen?. Podemos haber perjudicado el rendimiento de
las otras consultas, y lo que hemos hecho es desvestir a un santo para
vestir a otro.

Por ejemplo la consulta:

select * from LaTabla where DocNo = UnDocNo

se vería perjudicada, ya que ahora el índice (DocNo, AccNo) no es agrupado
y seguramente se tendría que recorrer toda la tabla porque hay muchos
registros con el mismo DocNo, pero eso yo no lo sé. Como no tengo toda la
información no puedo decir qué es lo mejor en este caso.

Sin embargo una consulta como esta:

select * from LaTabla where DocNo=UnDocNo and AccNo = UnAccNo

Se vería perjudicada en muy poca medida, se usaría el índice no agrupado
(DocNo, AccNo) que es único y la sobrecarga sería un bookmark lookup
adicional (4 páginas más leídas como mucho).

¿Qué consultas se hacen? ¿Qué selectividad tienen los índices? Yo qué sé. Si
lo supiera ya habría dado una respuesta concreta.

Saludos,

Jesús López
MVP

"Miguel Egea" escribió en el mensaje
news:
Jesús, no estoy de acuerdo en lo que se puede sobreentender de lo que


dices.

El resumen es que si SQL no necesita hacer un tableScan en ninguna


consulta
no se ve perjudicado, es decir si la indexación (ya sea clustered o no
clustered) es adecuada es muy probable que de exactamente igual que estén
particionadas como juntas.


-
Miguel Egea Gómez
Microsoft SQL-Server MVP
Webmaster de PortalSql.Com
¿Te interesa participar en las reuniones
del grupo de Usuarios de SQL-Server y .NET
Se harán en levante de España, (Alicante o Murcia)?


"SqlRanger" escribió en el mensaje
news:%
> Eso depende del tipo de consultas que se hagan sobre la tabla. Si la


tabla
> sólo se consulta por la fecha y por la clave primaria completa, podrías
> prescindir de particionar la tabla, teniendo un índice agrupado para la
> fecha y un índice no agrupado para la clave primaria. Teniendo un índice
> agrupado por la fecha, las consultas que tengan como criterio la fecha
> verán
> aumentado su rendimiento de forma espectacular.
>
> Ten en cuenta además que el particionamiento de la tabla no sólo puede
> aumentar el rendimiento de ciertas consultas, sino que también es
> beneficioso para ciertas operaciones, como copias de seguridad de


archivos
> y
> grupos de archivos, si cada tabla anual la pones en un archivo


diferente,
> no
> tienes que hacer copias de seguridad periódicas de ellas, con tener una
> copia es suficiente ya que no cambian los datos.
>
> Saludos
>
> Jesús López
> MVP
>
>
> "Pedro Jose Caceres" escribió en el mensaje
> news:u3vOK$
>> Ok... muy buena la discusión y se lo agradezco.
>>
>> Podemos concluir que para mi caso:
>> Si tengo un indice por la fecha no tengo necesidad de tener las


tablas
>> particionadas por año por más grandes que éstas sean ???
>> Díganme que si ! diganme que si!!! :))) seria un sueño para mi tener


una
>> sola tabla para movimientos y que no me afecte el registro diario
> intensivo
>> de transacciones.
>>
>>
>> Gracias
>>
>>
>>
>> "SqlRanger" wrote in message
>> news:
>> > Comentarios en línea,
>> >
>> > Saludos
>> >
>> > Jesús López
>> > MVP
>> >
>> >
>> > "Javier Loria" escribió en el mensaje
>> > news:
>> > > Hola:
>> > > >Porque algunos dicen que es inversamente proporcional?
>> > > No se, pero ese es un "Mito Urbano", probablemente


proveniente
> de
>> > SQL
>> > > 6.5 o de otras plataformas.Disculpa lo largo del mensaje pero es
>> > > mejor
>> que
>> > > lo pruebes.
>> > > El siguiente codigo te genera una tabla parecidas al esquema


que
> nos
>> > > comentaste, la columna blanco es solo para simular otras columnas.
>> > > TABLAS INDEPENDIENTES ==> >> > > CREATE TABLE Mov2001(
>> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
>> > > , Fecha SMALLDATETIME NOT NULL
>> > > , Nombre CHAR(20) NOT NULL
>> > > , Blanco CHAR(100) DEFAULT('')
>> > > )
>> > >
>> > > CREATE TABLE Mov2002(
>> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
>> > > , Fecha SMALLDATETIME NOT NULL
>> > > , Nombre CHAR(20) NOT NULL
>> > > , Blanco CHAR(100) DEFAULT('')
>> > > )
>> > >
>> > > CREATE TABLE Mov2003(
>> > > Id INT NOT NULL PRIMARY KEY CLUSTERED
>> > > , Fecha SMALLDATETIME NOT NULL
>> > > , Nombre CHAR(20) NOT NULL
>> > > , Blanco CHAR(100) DEFAULT('')
>> > > )
>> > > CREATE NONCLUSTERED INDEX IN_FechaMov2001
>> > > ON Mov2001(Fecha)
>> > > CREATE NONCLUSTERED INDEX IN_FechaMov2002
>> > > ON Mov2002(Fecha)
>> > > CREATE NONCLUSTERED INDEX IN_FechaMov2003
>> > > ON Mov2003(Fecha)
>> > > GO
>> > >
>> > > CREATE VIEW Movimientos AS
>> > > SELECT * FROM Mov2001 -- Pendiente eliminar *'s
>> > > UNION ALL
>> > > SELECT * FROM Mov2002
>> > > UNION ALL
>> > > SELECT * FROM Mov2003
>> > >
>> > > FIN DE TABLAS INDEPENDIENTES ==> >> > > Para simular la carga hice un script que genera n movimientos
>> > > diarios,
> y
>> > que
>> > > probe con 400 diarios que son solo 146,000 filas anuales, pero que
> bien
>> > > podrias cambiar a 15000 filas diarias
>> > > LLENADO DE TABLAS ==> >> > > DECLARE @NumeroDiario INT
>> > > SET @
>> > >
>> > > INSERT MOV2001(ID, Fecha, Nombre)
>> > > SELECT ((N1.Numero-1)*@NumeroDiario)+N2.Numero
>> > > , DATEADD(dd,N1.Numero-1,'2001/01/01')
>> > > , CONVERT(CHAR(10),DATEADD(dd,N1.Numero-1,'2001/01/01'),112)
>> > > + RIGHT(' '
>> > > +CAST(((N1.Numero-1)*@NumeroDiario)+N2.Numero AS


VARCHAR(7)),7)
>> > > FROM Numeros AS N1
>> > > CROSS JOIN Numeros AS N2
>> > > WHERE N1.Numero<366
>> > > AND N2.Numero<=@NumeroDiario
>> > >
>> > > INSERT Mov2002(ID, Fecha, Nombre)
>> > > SELECT Id+@NumeroDiario*365 , DATEADD(year, 1, Fecha)
>> > > , Nombre
>> > > FROM Mov2001
>> > >
>> > > INSERT Mov2003(ID, Fecha, Nombre)
>> > > SELECT Id+@NumeroDiario*365*2
>> > > , DATEADD(year, 1, Fecha)
>> > > , Nombre
>> > > FROM Mov2002
>> > > GO
>> > >
>> > > FIN DE LLENADO DE TABLAS ==> >> > > La consulta usa una tabla de numeros muy sencilla con una unica
>> > columna
>> > > que tiene los numeros del 1 en adelante, en tu caso deberia ser por
>> > > lo
>> > menos
>> > > hasta 15000.
>> > > Los resultados son:
>> > > ==> >> > > SELECT * FROM Mov2003 WHERE Fecha='2003-07-01'


reads
> 0,
>> > > read-ahead reads 0.
>> > > ==> >> > > SELECT * FROM Movimientos WHERE Fecha='2003-07-01'
>> > > 0,
>> > > read-ahead reads 0.
>> > > read-ahead reads 0.
>> > > read-ahead reads 0.
>> > > ==> >> > > La diferencia entre usar la vista y la tabla es casi nula (solo
> lee
>> el
>> > > encabezado del indice y la descarta). No hay cambios en el


desempeno
>> > > importantes por usar una u otra.
>> >
>> > Si hubiéramos puesto una restricción CHECK en las tablas que


asegurara
> que
>> > la fecha sólo puede ser del año correspondiente SQL Server no habría
>> tenido
>> > que ir al índice a comprobarlo y la diferencia entre tabla y vista
> habría
>> > sido completamente nula.
>> >
>> >
>> >
>> > > Si borras todo y creas una unica tabla de movimientos:
>> > > TABLA UNICA ==> >> > > CREATE TABLE Movimientos(
>> > > Id INT NOT NULL
>> > > PRIMARY KEY CLUSTERED
>> > > , Fecha SMALLDATETIME NOT NULL
>> > > , Nombre CHAR(20) NOT NULL
>> > > , Blanco CHAR(100) DEFAULT('')
>> > > )
>> > >
>> > > == FIN DE TABLA UNICA ==> >> > > CREATE NONCLUSTERED INDEX IN_FechaMovimientos
>> > > ON Movimientos(Fecha)
>> > >
>> > > DECLARE @NumeroDiario INT
>> > > SET @
>> > >
>> > > INSERT MOVIMIENTOS(ID, Fecha, Nombre)
>> > > SELECT ((N1.Numero-1)*@NumeroDiario)+N2.Numero AS Numero
>> > > ,DATEADD(dd,N1.Numero-1,'2001/01/01') AS Fecha
>> > > , CONVERT(CHAR(10),DATEADD(dd,N1.Numero-1,'2001/01/01'),112)
>> > > + RIGHT(' '
> +CAST(((N1.Numero-1)*@NumeroDiario)+N2.Numero
>> AS
>> > > VARCHAR(7)),7) as Nombre
>> > > FROM Numeros AS N1
>> > > CROSS JOIN Numeros AS N2
>> > > WHERE N1.Numero<366
>> > > AND N2.Numero<=@NumeroDiario
>> > >
>> > > INSERT Movimientos(ID, Fecha, Nombre)
>> > > SELECT Id+@NumeroDiario*365
>> > > , DATEADD(year, 1, Fecha)
>> > > , Nombre
>> > > FROM Movimientos
>> > > UNION ALL
>> > > SELECT Id+@NumeroDiario*365*2
>> > > , DATEADD(year, 1, Fecha)
>> > > , Nombre
>> > > FROM Mov2002
>> > > GO
>> > > SELECT * FROM Movimientos WHERE Fecha='2003-07-01'
>> > >


reads
> 0,
>> > > read-ahead reads 0.
>> > > ==> >> >
>> > Creo que aquí hay un error. La tabla es Movimientos, no Mov2003. El
> número
>> > de logical reads debería haber sido el triple. Ya que la consulta


hace
> una
>> > exploración completa de la tabla (no usa el índice de la fecha) y la
> tabla
>> > es tres veces más grande.
>> >
>> > > Veras que la consulta es exactamente igual que si usaras cada
> tabla
>> > por
>> > > separado. La estructura de indices de SQL hace que normalmente sea
>> > > mas
>> > > eficiente tener una sola tabla a n tablas iguales EXCEPTO cuando


cada
>> una
>> > de
>> > > las tabla va a un disco independiente. En cuyo caso la vista es lo
>> > > recomendable.
>> >
>> >
>> > No estoy de acuerdo.Creo que has cometido algún error en las pruebas.
>> >
>> > Para el caso de la consulta que estamos evaluando,. Será más


eficiente
> (el
>> > número de tablas más eficiente) particionar la tabla cuando el índice
>> sobre
>> > la Fecha es un índice no agrupado y la consulta devuelve un número de
>> > registros lo suficientemente grande como para que SQL Server


determine
> que
>> > es mejor una exploración de la tabla que usar el índice. La razón es
>> simple,
>> > SQL Server sólo tendrá que hacer la exploración completa de una de


las
>> > tablas, las otras tablas no las mirará ya que hay una restricción


CHECK
>> que
>> > se lo indica.
>> >
>> > Si el índice sobre la columna Fecha es agrupado, la diferencia entre
>> > particionar la tabla y no particionarala sería mínima, como mucho,
> habría
>> > una diferencia de una lectura lógica más con tabla única. Me estoy
>> > refiriendo, por supuesto, a consultas en las que se obtienen todos


las
>> > columnas y en la cláusula where está la columna de partición.
>> >
>> > > Es posible definir un JOB anual que agregue una tabla y


modifique
> la
>> > > vista actual si se requiere.
>> > >
>> > >
>> > > Javier Loria
>> > > Costa Rica
>> > > Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
>> > > que pueda ser copiado y pegado al Query Analizer.
>> > > La version de SQL y Service Pack tambien ayuda
>> > >
>> > > "Pedro Jose Caceres" wrote in message
>> > > news:
>> > > > > Hola:
>> > > > > El problema de esas tabla es que producen una perdida de
>> desempeno
>> > > > > importante, asi que considera la posiblidad de unirlas en una
>> > > > > sola
>> > > tabla,
>> > > > >
>> > > >
>> > > > Muchas gracias por la respuesta. Pero
>> > > > Ok.. entonces por qué algunos dicen que el tamaño de las tablas


es
>> > > > inversamente proporcional al buen desempeño ?
>> > > > A saber, son tablas de varios millones de registros (entre 4 y 5
>> > millones)
>> > > y
>> > > > son de operaciones diarias de uso intensivo y lo de la separacion
>> viene
>> > > > porque los nuevos registros son casi invariablemente de fecha del
> año
>> > > > actual, por tanto las demas no se utilizan a menos que sea en
> reportes
>> y
>> > > > consultas historicas.
>> > > > Como le dije a Miguel arriba, la razon de partirlas fue


basicamente
>> > > buscando
>> > > > mayor eficiencia en el registro diario de operaciones y creo que
>> > > > lei
>> por
>> > > ahi
>> > > > que esa era una forma de eficientizarlo.
>> > > > La verdad que a veces uno leyendo tantas opiniones distintas no
>> > > > sabe
>> por
>> > > > donde irse. :)
>> > > >
>> > > > >a
>> > > > > menos que cada una de ellas tenga su propio disco duro o


arreglo
> de
>> > > > discos.
>> > > > > Adicionalmente si no quieres fusionarlas lo mejor seria,
> usando
>> la
>> > > > > recomendacion de Miguel, crear una vista del tipo:
>> > > > > > >> > > > > CREATE VIEW Movimientos(Columna1, )
>> > > > > FROM
>> > > > > SELECT Columna1, Columna2 FROM Mov2001
>> > > > > UNION ALL -- *** ALL es muy importante
>> > > > > SELECT Columna1, Columna2 FROM Mov2002
>> > > > > UNION ALL
>> > > > >
>> > > >
>> > > >
>> > > > El problema es que la cerrar cada año, como dije arriba hay que
> crear
>> > una
>> > > > nueva tabla MovAAAA entonces implicaria modificar la vista ?


esto
> se
>> > > podria
>> > > > hacer en t-sql tambien ?
>> > > >
>> > > >
>> > > > > > >> > > > > Luego podras hacer un SELECT:
>> > > > > > >> > > > > SELECT Columna1, ... FROM Movimientos
>> > > > > WHERE ITEM='xyz' FECHA>='01/04/2001'
>> > > > > > >> > > > > Que sera muy rapido, porque por las estadisticas de SQL el
> sabra
>> > que
>> > > > > ninguna de las tablas, excepto la de Mov2004 tiene datos que
> cumplan
>> > la
>> > > > > condicion de las fechas..
>> > > > > Saludos,
>> > > > >
>> > > > >
>> > > > > Javier Loria
>> > > > > Costa Rica
>> > > > > Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
>> > > > > que pueda ser copiado y pegado al Query Analizer.
>> > > > > La version de SQL y Service Pack tambien ayuda
>> > > > >
>> > > > > "Pedro Jose Caceres" wrote in
>> > > > > message
>> > > > > news:#
>> > > > > > Tengo una tabla de movimientos para cada año, MOV2003,
>> > > > > > MOV2004,
>> > etc.
>> > > > > > Cuando se cierra un año por tanto, tengo que crear la nueva
> tabla
>> > > > > > correspondiente al nuevo año. Puedo hacer el CREATE TABLE en
>> t-sql
>> > > sin
>> > > > > > tener que sacar los usuarios del sistema ? Como puedo tomar


la
>> > > > estructura
>> > > > > de
>> > > > > > otra de las tablas ya existentes para que se cree igual ?
>> > > > > >
>> > > > > > Otra cosa es que para en una consulta ver movimientos que
> abarque
>> > dos
>> > > o
>> > > > > mas
>> > > > > > años, hago una UNION, preparando dinamicamente la


instruccion
>> > SELECT
>> > > > > desde
>> > > > > > la aplicacion y enviandola por odbc al servidor. Por ej. si


la
>> lista
>> > > de
>> > > > > > movimientos abarca va desde el 01/04/2001 al 31/03/2004,


estoy
>> > armando
>> > > > > desde
>> > > > > > el front-end la union asi::
>> > > > > >
>> > > > > >
>> > > > > > SELECT columna1, .., from MOV2001 WHERE ITEM='ELITEM'
>> > > > FECHA>/04/2001
>> > > > > > UNION
>> > > > > > SELECT columna1, .., from MOV2002 WHERE ITEM='ELITEM'
>> > > > > > UNION
>> > > > > > SELECT columna1, .., from MOV2003 WHERE ITEM='ELITEM'
>> > > > > > UNION
>> > > > > > SELECT columna1, .., from MOV2004 WHERE FECHA<1/03/2004
>> > > > > > ORDER BY FECHA
>> > > > > >
>> > > > > >
>> > > > > > Consideran que sea esta la mejor forma para hacer esto ?
>> > > > > >
>> > > > > > De no ser, que otras opciones hay para extraer esta


informacion
>> > quizas
>> > > > en
>> > > > > un
>> > > > > > SP del mismo servidor?
>> > > > > >
>> > > > > > Gracias
>> > > > > >
>> > > > > >
>> > > > >
>> > > > >
>> > > >
>> > > >
>> > >
>> > >
>> >
>> >
>>
>>
>
>


Respuesta Responder a este mensaje
#20 SqlRanger
11/10/2004 - 14:43 | Informe spam
Es decir, y como dice Miguel, aunque yo lo diría de otra manera:

Situación 1:
Todas las consultas que se hacen sobre la tabla usan un índice, es decir, no
requieren un recorrido completo de la tabla. Particionar la tabla no supone
un aumento del rendimiento, sólo una complicación.

Situación 2:
Hay consultas que aunque existe un índice que potencialmente podría usarse,
pero no se usa porque sería aún peor. O sea, hay consultas que requieren una
exploración completa de la tabla, estas consultas se verían beneficiadas si
particionamos la tabla por alguna de las columnas que aparecen en su
cláusula where.

Sin embargo podemos estar en la situación 2 y pudiera ser que eligiendo otro
índice como el índice agrupado pasemos directamente a la situación 1. Como
sugería en el mensaje anterior donde decía que el índice agrupado debería
ser por fecha y olvidarse de particionar la tabla. Pero yo no estoy seguro
de que eso vaya a ocurrir (pasar a situación 1) porque no sé que consultas
se hacen ni qué selectividad tienen.

Saludos:

Jesús López
MVP
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida