E se, de repente, ouvirem uma coisa destas?
A quantidade de colunas não importa num select, não estou a agregar nem ordenar a saída.
Pois, e eu já acreditei no Pai Natal, mas já foi há algum tempo.
Vamos criar umas tabelas para testar esta ideia?
create table MuitasColunas01
(
id1 int identity primary key
, Col1 varchar(255) not null
)
go
insert into MuitasColunas01
(Col1)
select 'Col1 da MuitasColunas01'
go 10
create table MuitasColunas02
(
id2 int identity primary key
, id_MuitasColunas01 int not null
, Col2 varchar(255) not null
)
go
insert into MuitasColunas02
(id_MuitasColunas01, Col2)
select (ABS(CHECKSUM(NEWID()))%10)+1
, 'Col1 da MuitasColunas02'
go 1000
create table MuitasColunas03
(
id3 int identity primary key
, id_MuitasColunas02 int not null
, Col3 varchar(255) not null
)
go
insert into MuitasColunas03
(id_MuitasColunas02, Col3)
select (ABS(CHECKSUM(NEWID()))%1000)+1
, 'Col1 da MuitasColunas03'
go 10000
Podemos agora correr este pedacinho de código?
set statistics time, io on
select *
from MuitasColunas01 a
inner join MuitasColunas02 b
on b.id_MuitasColunas01 = a.id1
inner join MuitasColunas03 c
on c.id_MuitasColunas02 = b.id2



Nada de estranho se passa, como esperado.
Mas no fundo o que queríamos era apenas encontrar o id3 e a Col1 da MuitasColunas03
select c.id3
, c.Col3
from MuitasColunas01 a
inner join MuitasColunas02 b
on b.id_MuitasColunas01 = a.id1
inner join MuitasColunas03 c
on c.id_MuitasColunas02 = b.id2


Nada de diferente…
Claro. Ainda não dissémos ao SQL Server que as relações existem!
ALTER TABLE MuitasColunas02
ADD CONSTRAINT
MuitasColunas02_id_MuitasColunas01 FOREIGN KEY(id_MuitasColunas01)
REFERENCES MuitasColunas01 (id1)
ALTER TABLE MuitasColunas03
ADD CONSTRAINT
MuitasColunas03_id_MuitasColunas02 FOREIGN KEY(id_MuitasColunas02)
REFERENCES MuitasColunas02 (id2)
select c.id3
, c.Col3
from MuitasColunas01 a
inner join MuitasColunas02 b
on b.id_MuitasColunas01 = a.id1
inner join MuitasColunas03 c
on c.id_MuitasColunas02 = b.id2


Join elimination, ainda se lembram?
E neste momento estão a dizer que isto é um pouco estúpido. E até é. Ninguém no seu perfeito juízo faria uma coisa destas.
Aceito completamente.
Mas… e se não soubessem que era assim, ou se já não se lembrassem que era assim?
Basta-me criar uma vista e não vos dar acesso à definição da mesma. Ou, pior ainda e mais usual, até fomos nós que criámos a vista mas já foi há algum tempo e já não nos lembramos…
create view dbo.UmaVistaQueNaoMeLembro
as
select *
from MuitasColunas01 a
inner join MuitasColunas02 b
on b.id_MuitasColunas01 = a.id1
inner join MuitasColunas03 c
on c.id_MuitasColunas02 = b.id2
go
Vamos ver as diferenças?
select *
from UmaVistaQueNaoMeLembro
select id3
, Col3
from UmaVistaQueNaoMeLembro


Os joins desaparecem, não tocamos nas outras tabelas, não precisamos de grant de memória.
A quantidade de colunas não importa num select, não estou a agregar nem ordenar a saída?
Importa sim senhor.