Ayuda en Optimizacion de Vista

19/02/2004 - 20:55 por Dany Acosta | Informe spam
Amigos es recomendale Contruir una vista que contenga sentencias
UNION ALL

Ejmplo.

Create View Vista1 AS
Select Campo1,Campo2,Campo3,Campo4 From tabla1
union all
select campo1,campo2,campo3, campo4 from tabla2
union all
select campo1, campo2, campo3, campo4 from tabla3

y despues obtener mediante otra sentencia un acumulado osea

select campo1,sum(campo3) as Sum_Campo3, Sum(Campo4) as Sum_Campo4
From Vista1 Where campo1='XXX' and Campo2<1000.00
Group by campo1

Sabiendo que Cada Tabla contiene por Año
Tabla1 --> 10,000 Registros
Tabla2 --> 600,000 Registros
Tabla3 --> 300,000 Registros

Espero sus comentarios sobre si es Optimo la vista de esta manera o que
otra existe de hacerlo optima ya que los datos que necesito estan en
las tres tablas y necesito acumular por todo..

Gracias

Dany Acosta

Preguntas similare

Leer las respuestas

#1 Maximiliano Damian Accotto
19/02/2004 - 23:22 | Informe spam
Hola, malo no es si tienes buenos indices y todo ello, pero quizas podamos
ver otra alternativa, debes primero ver si se pueden vincular no pero
podrias de ver algo asi como:


Select tusprimeroscampos from tuprimertabla join (select campos from tu
segundatabla) dos
on tuprimertabla.campoid = dos.campoid

Adentro del Join podrias poner max,min, lo que haga falta.

Luego adelante podes usar tambien max pero sobre la segunda tabla, algo asi
como:

max(dos.campo) as pepe

y asi!! tambien podrias tener los campos en columnas de esta forma y luego
solo surmarlos con un simlple plus

Ahora por la cantidad de registros mirarias esto:

1.Solo seleccionar los campos que sean necesario y no usar el *
2.Tener buenos indices para los join y los where


Con esto deberias andar lo mas bien, una cosa que podes probar es en cuanto
pone denso al Servidor, esto lo podes hacer con el Visor de Sucesos y ahi
podes por ej monitoriar:

% Cpu
Cantidad de Bloqueos
Tiempo de espera de Bloqueos
Paginas /seg


Salu2

Maximiliano Damian Accotto
Gerente de IT
Fundicion San Cayetano S.A.
Buenos Aires Argentina
-
maxi_accotto[arroba]speedy[.]com[.].ar
MSN:



"Dany Acosta" escribió en el mensaje
news:
Amigos es recomendale Contruir una vista que contenga sentencias
UNION ALL

Ejmplo.

Create View Vista1 AS
Select Campo1,Campo2,Campo3,Campo4 From tabla1
union all
select campo1,campo2,campo3, campo4 from tabla2
union all
select campo1, campo2, campo3, campo4 from tabla3

y despues obtener mediante otra sentencia un acumulado osea

select campo1,sum(campo3) as Sum_Campo3, Sum(Campo4) as Sum_Campo4
From Vista1 Where campo1='XXX' and Campo2<1000.00
Group by campo1

Sabiendo que Cada Tabla contiene por Año
Tabla1 --> 10,000 Registros
Tabla2 --> 600,000 Registros
Tabla3 --> 300,000 Registros

Espero sus comentarios sobre si es Optimo la vista de esta manera o que
otra existe de hacerlo optima ya que los datos que necesito estan en
las tres tablas y necesito acumular por todo..

Gracias

Dany Acosta

Respuesta Responder a este mensaje
#2 Dany Acosta
20/02/2004 - 00:22 | Informe spam
Amigo Lastimosamente los Joins No me sirven porque necesito que vengan
en orden los registros me explico..
Tengo que tener este resultado.
Campo1 Fecha campo2 campo3 campo4 opcion
xxxxx 15/03 150 500 3000 1
aaaaa 01/04 300 100 1524 3
ffff 04/03 514 142 154 2

Para despues obtener esto hacer acumulado y ordernar por fecha
ya que necesito recorrer la tabla unidad para poder obtener un saldo.

Gracias



Maximiliano Damian Accotto wrote:

Hola, malo no es si tienes buenos indices y todo ello, pero quizas podamos
ver otra alternativa, debes primero ver si se pueden vincular no pero
podrias de ver algo asi como:


Select tusprimeroscampos from tuprimertabla join (select campos from tu
segundatabla) dos
on tuprimertabla.campoid = dos.campoid

Adentro del Join podrias poner max,min, lo que haga falta.

Luego adelante podes usar tambien max pero sobre la segunda tabla, algo asi
como:

max(dos.campo) as pepe

y asi!! tambien podrias tener los campos en columnas de esta forma y luego
solo surmarlos con un simlple plus

Ahora por la cantidad de registros mirarias esto:

1.Solo seleccionar los campos que sean necesario y no usar el *
2.Tener buenos indices para los join y los where


Con esto deberias andar lo mas bien, una cosa que podes probar es en cuanto
pone denso al Servidor, esto lo podes hacer con el Visor de Sucesos y ahi
podes por ej monitoriar:

% Cpu
Cantidad de Bloqueos
Tiempo de espera de Bloqueos
Paginas /seg

Respuesta Responder a este mensaje
#3 Maximiliano Damian Accotto
20/02/2004 - 00:34 | Informe spam
s correcto lo que yo te digo, que ese acumulado quizas lo podes tener en una
columna y luego sumarlas me explico?

Ahora si no se pueden vincular perdiste :(


Salu2

Maximiliano Damian Accotto
Gerente de IT
Fundicion San Cayetano S.A.
Buenos Aires Argentina
-
maxi_accotto[arroba]speedy[.]com[.].ar
MSN:



"Dany Acosta" escribió en el mensaje
news:
Amigo Lastimosamente los Joins No me sirven porque necesito que vengan
en orden los registros me explico..
Tengo que tener este resultado.
Campo1 Fecha campo2 campo3 campo4 opcion
xxxxx 15/03 150 500 3000 1
aaaaa 01/04 300 100 1524 3
ffff 04/03 514 142 154 2

Para despues obtener esto hacer acumulado y ordernar por fecha
ya que necesito recorrer la tabla unidad para poder obtener un saldo.

Gracias



Maximiliano Damian Accotto wrote:

> Hola, malo no es si tienes buenos indices y todo ello, pero quizas


podamos
> ver otra alternativa, debes primero ver si se pueden vincular no pero
> podrias de ver algo asi como:
>
>
> Select tusprimeroscampos from tuprimertabla join (select campos from tu
> segundatabla) dos
> on tuprimertabla.campoid = dos.campoid
>
> Adentro del Join podrias poner max,min, lo que haga falta.
>
> Luego adelante podes usar tambien max pero sobre la segunda tabla, algo


asi
> como:
>
> max(dos.campo) as pepe
>
> y asi!! tambien podrias tener los campos en columnas de esta forma y


luego
> solo surmarlos con un simlple plus
>
> Ahora por la cantidad de registros mirarias esto:
>
> 1.Solo seleccionar los campos que sean necesario y no usar el *
> 2.Tener buenos indices para los join y los where
>
>
> Con esto deberias andar lo mas bien, una cosa que podes probar es en


cuanto
> pone denso al Servidor, esto lo podes hacer con el Visor de Sucesos y


ahi
> podes por ej monitoriar:
>
> % Cpu
> Cantidad de Bloqueos
> Tiempo de espera de Bloqueos
> Paginas /seg
>

Respuesta Responder a este mensaje
#4 Javier Loria
20/02/2004 - 15:28 | Informe spam
Hola Dany:
En mi opinion si es recomendable, de hecho es una tecnica de
optimizacion de Tablas muy grandes. La ventajas es que este tipo de diseno
permite dividir una tabla en multiples discos o incluso en multiples
servidores.
Hacer un UNION ALL de la misma tabla es el que normalmente no es
recomendable desde el punto de vista de desempeno.
Por otro lado, si las Tablas son iguales en su estructura, se debe
cuestionar el disenador si no deberian estar representadas en una sola
tabla, pero eso depende de la entidad que estes modelando.
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.
Dany Acosta escribio:
Amigos es recomendale Contruir una vista que contenga sentencias
UNION ALL

Ejmplo.

Create View Vista1 AS
Select Campo1,Campo2,Campo3,Campo4 From tabla1
union all
select campo1,campo2,campo3, campo4 from tabla2
union all
select campo1, campo2, campo3, campo4 from tabla3

y despues obtener mediante otra sentencia un acumulado osea

select campo1,sum(campo3) as Sum_Campo3, Sum(Campo4) as Sum_Campo4
From Vista1 Where campo1='XXX' and Campo2<1000.00
Group by campo1

Sabiendo que Cada Tabla contiene por Año
Tabla1 --> 10,000 Registros
Tabla2 --> 600,000 Registros
Tabla3 --> 300,000 Registros

Espero sus comentarios sobre si es Optimo la vista de esta manera o
que otra existe de hacerlo optima ya que los datos que necesito
estan en las tres tablas y necesito acumular por todo..

Gracias

Dany Acosta
Respuesta Responder a este mensaje
#5 Javier Loria
20/02/2004 - 16:36 | Informe spam
Hola Adrian:
En contra del sentido comun, la respuesta es NO. No va ha hacer un
conjunto de todos los datos y luego sumarizarlos. Las vistas se optimizan
justo con la sentencia. Muy facil escribirlo, no tan facil probarlo :(
Creacion de las Tablas
CREATE TABLE Tabla1 (
Zona INTEGER NOT NULL
CHECK(Zona=1)
DEFAULT (1),
Numero INTEGER NOT NULL,
Valor INTEGER NOT NULL,
Relleno CHAR(100),
CONSTRAINT PK_TABLA1
PRIMARY KEY (Zona, Numero)
)

CREATE TABLE Tabla2 (
Zona INTEGER NOT NULL
CHECK(Zona=2)
DEFAULT (2),
Numero INTEGER NOT NULL,
Valor INTEGER NOT NULL,
Relleno CHAR(100),
CONSTRAINT PK_TABLA2
PRIMARY KEY (Zona, Numero)
)

CREATE TABLE Tabla3 (
Zona INTEGER NOT NULL
CHECK(Zona=3)
DEFAULT (3),
Numero INTEGER NOT NULL,
Valor INTEGER NOT NULL,
Relleno CHAR(100),
CONSTRAINT PK_TABLA3
PRIMARY KEY (Zona, Numero)
)

CREATE VIEW Tabla123
AS
SELECT Zona, Numero, Valor, Relleno FROM Tabla1
UNION ALL
SELECT Zona, Numero, Valor, Relleno FROM Tabla2
UNION ALL
SELECT Zona, Numero, Valor, Relleno FROM Tabla3

Las tablas 1,2 y 3 son "exactamente iguales excepto que cada una tiene una
columna zona que es una "constante" o el atributo que separa que dato esta
en cada tabla. La columna RELLENO es solo para simular otras columnas que
gasten espacio (sino todo se hace para TableScan, porque la tabla es muy
pequeno y no se beneficia de los indices).
Insertemos +2000 Filas
INSERT Tabla1(Numero, Valor)
SELECT 1,1 UNION ALL
SELECT 2,2 UNION ALL
SELECT 3,3 UNION ALL
SELECT 4,4 UNION ALL
SELECT 5,5

INSERT Tabla1(Numero, Valor)
SELECT Numero+5, Valor+5 FROM Tabla1

INSERT Tabla1(Numero, Valor)
SELECT Numero+10, Valor+10 FROM Tabla1

INSERT Tabla1(Numero, Valor)
SELECT Numero+20, Valor+20 FROM Tabla1

INSERT Tabla1(Numero, Valor)
SELECT Numero+40, Valor+40 FROM Tabla1

INSERT Tabla1(Numero, Valor)
SELECT Numero+80, Valor+80 FROM Tabla1

INSERT Tabla1(Numero, Valor)
SELECT Numero+160, Valor+160 FROM Tabla1

INSERT Tabla1(Numero, Valor)
SELECT Numero+320, Valor+320 FROM Tabla1

INSERT Tabla1(Numero, Valor)
SELECT Numero+640, Valor+640 FROM Tabla1

INSERT Tabla1(Numero, Valor)
SELECT Numero+1280, Valor+1280 FROM Tabla1

INSERT Tabla2(Numero, Valor)
SELECT Numero, Valor FROM Tabla1
INSERT Tabla3(Numero, Valor)
SELECT Numero, Valor FROM Tabla1
Si revisamos los planes de acceso de algunas consultas veriamos como accesa
el servidor las tablas:
a) SELECT Zona, Numero FROM Tabla123
WHERE Numero 0 AND Zona=2
Observaciones: Hace unicamente un Clustered Index Scan sobre la
PK_Tabla2, con una estimacion de 1 fila. Rapido, Rapido, Rapido!!!.
b) SELECT Zona, Numero FROM Tabla123
WHERE Numero 0
Observaciones: Hace 3 Clustered Index Scan sobre los indices de las
llaves primarias con una estimacion de 1 fila cada uno. Rapido!!!, La unica
forma mas rapida de resolver esta consulta es un indice sobre la columna
Numero. Podria construirse sobre la vista dicho indice si fuera necesario.
c) SELECT Zona, Numero, SUM(Valor)
FROM Tabla123
WHERE Numero 0
GROUP BY Zona, Numero
Observaciones: Igual que el anterior, solo que agrega el compute Scalar.
En conclusion, nunca el servidor de SQL leyo todas los datos, solo leyo
los que requeria, aplicando primero el Where y usando los indices adecuados,
y luego agrupo.
Este tipo de tecnologia de Optimizacion del SQL 2000 siempre me ha
parecido "Alucinante".

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.
.

Adrian D. Garcia escribio:
Hmmm... a ver.
Si haces el UNION ALL de todos ellos vas a tener un resultado de
910.000 filas.
Luego vas a quere sumarizar y ordenar por fechas.
El resultado intermedio no va a tener ningun indice ni nada parecido
por lo cual para la suma y el ordenamiento el motor va a tener qu e
recorrer toda las paginas de este resultado.
No podrias primero sumarizar cada una de las tablas y luego realizar
un UNION ALL?


"Dany Acosta" wrote in message
news:
Amigos es recomendale Contruir una vista que contenga sentencias
UNION ALL

Ejmplo.

Create View Vista1 AS
Select Campo1,Campo2,Campo3,Campo4 From tabla1
union all
select campo1,campo2,campo3, campo4 from tabla2
union all
select campo1, campo2, campo3, campo4 from tabla3

y despues obtener mediante otra sentencia un acumulado osea

select campo1,sum(campo3) as Sum_Campo3, Sum(Campo4) as Sum_Campo4
From Vista1 Where campo1='XXX' and Campo2<1000.00
Group by campo1

Sabiendo que Cada Tabla contiene por Año
Tabla1 --> 10,000 Registros
Tabla2 --> 600,000 Registros
Tabla3 --> 300,000 Registros

Espero sus comentarios sobre si es Optimo la vista de esta manera o
que otra existe de hacerlo optima ya que los datos que necesito
estan en las tres tablas y necesito acumular por todo..

Gracias

Dany Acosta
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida