Llaves compuestas

07/11/2005 - 04:09 por Antonio Ortiz | Informe spam
En la auditoria que estoy haciendo, encuentro la mayoria de las tablas con
un unico indice compuesto, con hasta 8 campos. Sin embargo, en el Analizador
de SQL, veo que algunas consultas se relacionan por alguna columna no
indexada, tanto en donde es (o debera) ser llave primaria y llave
secundaria. He procedido a indexar ambas columnas en las 2 tablas.

Segun mi apreciacion, el indice compuesto, no sirve de mucho para estas
consultas. Me estoy perdiendo algo que no estoy detectando o pueden darme
algun comentario?


saludos a todos,


Antonio Ortiz
ant(a)aortiz.net
www.aortiz.net
www.progvisual.com

Preguntas similare

Leer las respuestas

#1 Maxi
07/11/2005 - 12:48 | Informe spam
Hola, no, no es asi la cosa!!, los indices compuestos son utiles si estan
bien armados y luego las consultas los usan bien, ahora hacer un indice
compuesto por 8 campos mmm a mi no me gusta mucho eso


Salu2
Maxi [MVP SQL SERVER]


"Antonio Ortiz" escribió en el mensaje
news:
En la auditoria que estoy haciendo, encuentro la mayoria de las tablas con
un unico indice compuesto, con hasta 8 campos. Sin embargo, en el
Analizador de SQL, veo que algunas consultas se relacionan por alguna
columna no indexada, tanto en donde es (o debera) ser llave primaria y
llave secundaria. He procedido a indexar ambas columnas en las 2 tablas.

Segun mi apreciacion, el indice compuesto, no sirve de mucho para estas
consultas. Me estoy perdiendo algo que no estoy detectando o pueden darme
algun comentario?


saludos a todos,


Antonio Ortiz
ant(a)aortiz.net
www.aortiz.net
www.progvisual.com


Respuesta Responder a este mensaje
#2 Alejandro Mesa
07/11/2005 - 15:00 | Informe spam
Antonio Ortiz,

Segun lo que comentas, algo no esta bien en ese esquema. Toda tabla debe
tener una clave primaria, y sql server crea por defecto un indice clustered
por ella. En cambio, sql server no crea ningun indice para restricciones de
clave foranea y por ende se debe crear un indice por ellas para que sql
server puede hacer uso de ellos cuando se hace un join usando estas columnas
o esa relacion. Algo se debe tener muy en cuenta cuando hablamos de indices
compuestos y esto es que el indice sera usado efectivamente solamente si en
la consulta aparece la columna mas a la izquierda en la definicion de la
clave de ese indice, puesto que sql server solo guarda el histograma de esa
columna y la densidad de la composicion de esta columna y con el resto.

Ejemplo:

use northwind
go

create nonclustered index ix_nc_customers_country_city on customers(country,
city)
go

dbcc show_statistics (customers, ix_nc_customers_country_city)
go

set showplan_text on
go

select *
from dbo.customers
where country = 'France'
go

select *
from dbo.customers
where country = 'France' and city = 'Paris'
go

select customerid, country, city
from dbo.customers
where country = 'France' and city = 'Paris' and customerid = 'PARIS'
go

select customerid, country, city
from dbo.customers
where city = 'Paris'
go

set showplan_text on
go

drop index dbo.customers.ix_nc_customers_country_city
go


create nonclustered index ix_nc_customers_country_city on customers(country,
city)
go

Statistics for INDEX 'ix_nc_customers_country_city'.
Updated Rows Rows Sampled Steps
Density Average key length

Nov 7 2005 8:46AM 91 91 21 0.0
37.582417

(1 row(s) affected)

All density Average Length Columns




















































-
4.7619049E-2 11.560439 Country
1.4492754E-2 27.582417 Country, City
1.0989011E-2 37.582417 Country, City, CustomerID

(3 row(s) affected)

RANGE_HI_KEY RANGE_ROWS EQ_ROWS
DISTINCT_RANGE_ROWS AVG_RANGE_ROWS

Argentina 0.0 3.0 0
0.0
Austria 0.0 2.0 0
0.0
Belgium 0.0 2.0 0
0.0
Brazil 0.0 9.0 0
0.0
Canada 0.0 3.0 0
0.0
Denmark 0.0 2.0 0
0.0
Finland 0.0 2.0 0
0.0
France 0.0 11.0 0
0.0
Germany 0.0 11.0 0
0.0
Ireland 0.0 1.0 0
0.0
Italy 0.0 3.0 0
0.0
Mexico 0.0 5.0 0
0.0
Norway 0.0 1.0 0
0.0
Poland 0.0 1.0 0
0.0
Portugal 0.0 2.0 0
0.0
Spain 0.0 5.0 0
0.0
Sweden 0.0 2.0 0
0.0
Switzerland 0.0 2.0 0
0.0
UK 0.0 7.0 0
0.0
USA 0.0 13.0 0
0.0
Venezuela 0.0 4.0 0
0.0

(21 row(s) affected)

DBCC execution completed. If DBCC printed error messages, contact your
system administrator.
StmtText
-

select *
from dbo.customers
where country = 'France'

(1 row(s) affected)

StmtText

|--Bookmark Lookup(BOOKMARK:([Bmk1000]),
OBJECT:([Northwind].[dbo].[Customers]))
|--Index
Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
SEEK:([Customers].[Country]=Convert([@1])) ORDERED FORWARD)

(2 row(s) affected)

StmtText

select *
from dbo.customers
where country = 'France' and city = 'Paris'

(1 row(s) affected)

StmtText



|--Bookmark Lookup(BOOKMARK:([Bmk1000]),
OBJECT:([Northwind].[dbo].[Customers]))
|--Index
Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
SEEK:([Customers].[Country]=Convert([@1]) AND
[Customers].[City]=Convert([@2])) ORDERED FORWARD)

(2 row(s) affected)

StmtText



select customerid, country, city
from dbo.customers
where country = 'France' and city = 'Paris' and customerid = 'PARIS'

(1 row(s) affected)

StmtText


|--Index
Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
SEEK:([Customers].[Country]=Convert([@1]) AND
[Customers].[City]=Convert([@2]) AND [Customers].[CustomerID]=Convert([@3]))
ORDERED FORWARD)

(1 row(s) affected)

StmtText



select customerid, country, city
from dbo.customers
where city = 'Paris'

(1 row(s) affected)

StmtText

-
|--Index
Scan(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
WHERE:([Customers].[City]=Convert([@1])))

(1 row(s) affected)

Vamos ahora a comentar sobre el plan de ejecucion escojido por sql server
para cada sentencia "select"

Para la primera, sugunda y tercera sentencia "select", sql server escojio
hacer un "index seek" en el indice ].[ix_nc_customers_country_city], esto se
debe a que las tres sentencias incluyen un argumento de busqueda por la
columna mas a la izquierda en la clave del indice (country). Un caso especial
es la tercera sentencia, donde a diferencia con la primera y segunda, sql
server solo hace un "index seek" sin necesidad de hacer un "Bookmark Lookup"
y esto se debe a que el indice cubre todas las columnas que son referenciadas
en la sentencia (country, city y customerid) ya que el indice clustered de
esa tabla es por la columna "customerid" y como todos sabemos, sql server
referencia esta clave en todos los indices nonclustered de la tabla. Este
tipo de indice se conoce como "covering index". En cambio, para la cuarta
sentencia, sql server escoje hacer un "index scan" en ese indice en vez de un
"index seek" y esto se debe principalmente a que en la consulta no aparece un
argumento de busqueda por "country".

Espero te haya servido de ayuda,


AMB

"Antonio Ortiz" wrote:

En la auditoria que estoy haciendo, encuentro la mayoria de las tablas con
un unico indice compuesto, con hasta 8 campos. Sin embargo, en el Analizador
de SQL, veo que algunas consultas se relacionan por alguna columna no
indexada, tanto en donde es (o debera) ser llave primaria y llave
secundaria. He procedido a indexar ambas columnas en las 2 tablas.

Segun mi apreciacion, el indice compuesto, no sirve de mucho para estas
consultas. Me estoy perdiendo algo que no estoy detectando o pueden darme
algun comentario?


saludos a todos,


Antonio Ortiz
ant(a)aortiz.net
www.aortiz.net
www.progvisual.com



Respuesta Responder a este mensaje
#3 Antonio Ortiz
07/11/2005 - 17:03 | Informe spam
mm, interesante, anoche me puse a buscar documentacion sobre indices
compuestos y encontre lo que mencionas, el indice compuesto sera utilizado
si se utiliza la columna mas a la izquierda.

En las consultas que encontre no es asi, por ejemplo:

Indice compuesto: ( NoProducto, NoCuenta, NoFolio, NoCliente,
ClaveProveedor )

Consulta: Select Movs.* From Clientes, Movs Where Clientes.NoCliente Movs.NoCliente
* Por cierto encontre consultas de este tipo, que ya las conocia, pero yo
prefiero la notacion:
Clientes.NoCliente = Movs.NoCliente

Alguien podria opinar sobre las diferencias en funcionalidad entre ellas?


gracias,

Antonio Ortiz Ramirez
asesor en sistemas
ant(a)aortiz.net
www.aortiz.net
www.visualcaja.com
www.progvisual.com




"Alejandro Mesa" escribió en el
mensaje news:
Antonio Ortiz,

Segun lo que comentas, algo no esta bien en ese esquema. Toda tabla debe
tener una clave primaria, y sql server crea por defecto un indice


clustered
por ella. En cambio, sql server no crea ningun indice para restricciones


de
clave foranea y por ende se debe crear un indice por ellas para que sql
server puede hacer uso de ellos cuando se hace un join usando estas


columnas
o esa relacion. Algo se debe tener muy en cuenta cuando hablamos de


indices
compuestos y esto es que el indice sera usado efectivamente solamente si


en
la consulta aparece la columna mas a la izquierda en la definicion de la
clave de ese indice, puesto que sql server solo guarda el histograma de


esa
columna y la densidad de la composicion de esta columna y con el resto.

Ejemplo:

use northwind
go

create nonclustered index ix_nc_customers_country_city on


customers(country,
city)
go

dbcc show_statistics (customers, ix_nc_customers_country_city)
go

set showplan_text on
go

select *
from dbo.customers
where country = 'France'
go

select *
from dbo.customers
where country = 'France' and city = 'Paris'
go

select customerid, country, city
from dbo.customers
where country = 'France' and city = 'Paris' and customerid = 'PARIS'
go

select customerid, country, city
from dbo.customers
where city = 'Paris'
go

set showplan_text on
go

drop index dbo.customers.ix_nc_customers_country_city
go


create nonclustered index ix_nc_customers_country_city on


customers(country,
city)
go

Statistics for INDEX 'ix_nc_customers_country_city'.
Updated Rows Rows Sampled Steps
Density Average key length

Nov 7 2005 8:46AM 91 91 21 0.0
37.582417

(1 row(s) affected)

All density Average Length Columns






















































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
4.7619049E-2 11.560439 Country
1.4492754E-2 27.582417 Country, City
1.0989011E-2 37.582417 Country, City,


CustomerID

(3 row(s) affected)

RANGE_HI_KEY RANGE_ROWS EQ_ROWS
DISTINCT_RANGE_ROWS AVG_RANGE_ROWS

Argentina 0.0 3.0 0
0.0
Austria 0.0 2.0 0
0.0
Belgium 0.0 2.0 0
0.0
Brazil 0.0 9.0 0
0.0
Canada 0.0 3.0 0
0.0
Denmark 0.0 2.0 0
0.0
Finland 0.0 2.0 0
0.0
France 0.0 11.0 0
0.0
Germany 0.0 11.0 0
0.0
Ireland 0.0 1.0 0
0.0
Italy 0.0 3.0 0
0.0
Mexico 0.0 5.0 0
0.0
Norway 0.0 1.0 0
0.0
Poland 0.0 1.0 0
0.0
Portugal 0.0 2.0 0
0.0
Spain 0.0 5.0 0
0.0
Sweden 0.0 2.0 0
0.0
Switzerland 0.0 2.0 0
0.0
UK 0.0 7.0 0
0.0
USA 0.0 13.0 0
0.0
Venezuela 0.0 4.0 0
0.0

(21 row(s) affected)

DBCC execution completed. If DBCC printed error messages, contact your
system administrator.
StmtText
-

select *
from dbo.customers
where country = 'France'

(1 row(s) affected)

StmtText



-
|--Bookmark Lookup(BOOKMARK:([Bmk1000]),
OBJECT:([Northwind].[dbo].[Customers]))
|--Index



Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
SEEK:([Customers].[Country]=Convert([@1])) ORDERED FORWARD)

(2 row(s) affected)

StmtText


select *
from dbo.customers
where country = 'France' and city = 'Paris'

(1 row(s) affected)

StmtText




-

|--Bookmark Lookup(BOOKMARK:([Bmk1000]),
OBJECT:([Northwind].[dbo].[Customers]))
|--Index



Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
SEEK:([Customers].[Country]=Convert([@1]) AND
[Customers].[City]=Convert([@2])) ORDERED FORWARD)

(2 row(s) affected)

StmtText



-

select customerid, country, city
from dbo.customers
where country = 'France' and city = 'Paris' and customerid = 'PARIS'

(1 row(s) affected)

StmtText




-
-
-
|--Index



Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
SEEK:([Customers].[Country]=Convert([@1]) AND
[Customers].[City]=Convert([@2]) AND


[Customers].[CustomerID]=Convert([@3]))
ORDERED FORWARD)

(1 row(s) affected)

StmtText



-

select customerid, country, city
from dbo.customers
where city = 'Paris'

(1 row(s) affected)

StmtText

|--Index



Scan(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
WHERE:([Customers].[City]=Convert([@1])))

(1 row(s) affected)

Vamos ahora a comentar sobre el plan de ejecucion escojido por sql server
para cada sentencia "select"

Para la primera, sugunda y tercera sentencia "select", sql server escojio
hacer un "index seek" en el indice ].[ix_nc_customers_country_city], esto


se
debe a que las tres sentencias incluyen un argumento de busqueda por la
columna mas a la izquierda en la clave del indice (country). Un caso


especial
es la tercera sentencia, donde a diferencia con la primera y segunda, sql
server solo hace un "index seek" sin necesidad de hacer un "Bookmark


Lookup"
y esto se debe a que el indice cubre todas las columnas que son


referenciadas
en la sentencia (country, city y customerid) ya que el indice clustered de
esa tabla es por la columna "customerid" y como todos sabemos, sql server
referencia esta clave en todos los indices nonclustered de la tabla. Este
tipo de indice se conoce como "covering index". En cambio, para la cuarta
sentencia, sql server escoje hacer un "index scan" en ese indice en vez de


un
"index seek" y esto se debe principalmente a que en la consulta no aparece


un
argumento de busqueda por "country".

Espero te haya servido de ayuda,


AMB

"Antonio Ortiz" wrote:

> En la auditoria que estoy haciendo, encuentro la mayoria de las tablas


con
> un unico indice compuesto, con hasta 8 campos. Sin embargo, en el


Analizador
> de SQL, veo que algunas consultas se relacionan por alguna columna no
> indexada, tanto en donde es (o debera) ser llave primaria y llave
> secundaria. He procedido a indexar ambas columnas en las 2 tablas.
>
> Segun mi apreciacion, el indice compuesto, no sirve de mucho para estas
> consultas. Me estoy perdiendo algo que no estoy detectando o pueden


darme
> algun comentario?
>
>
> saludos a todos,
>
>
> Antonio Ortiz
> ant(a)aortiz.net
> www.aortiz.net
> www.progvisual.com
>
>
>
Respuesta Responder a este mensaje
#4 Carlos Sacristán
07/11/2005 - 17:24 | Informe spam
En la consulta que envías el índice compuesto no sirve de nada porque no
es posible llegar al campo NoCliente sin haber pasado previamente por
NoProducto, NoCuenta y NoFolio

Entre hacer el join en el WHERE o en el JOIN no hay diferencias de
rendimiento. Yo prefiero la segunda opción porque me parece más claro,
pudiendo distinguir de un plumazo los criterios de búsqueda de los criterios
de combinación


Un saludo

-
"Sólo sé que no sé nada. " (Sócrates)

"Antonio Ortiz" escribió en el mensaje
news:
mm, interesante, anoche me puse a buscar documentacion sobre indices
compuestos y encontre lo que mencionas, el indice compuesto sera utilizado
si se utiliza la columna mas a la izquierda.

En las consultas que encontre no es asi, por ejemplo:

Indice compuesto: ( NoProducto, NoCuenta, NoFolio, NoCliente,
ClaveProveedor )

Consulta: Select Movs.* From Clientes, Movs Where Clientes.NoCliente
Movs.NoCliente
* Por cierto encontre consultas de este tipo, que ya las conocia, pero yo
prefiero la notacion:
Clientes.NoCliente = Movs.NoCliente

Alguien podria opinar sobre las diferencias en funcionalidad entre ellas?


gracias,

Antonio Ortiz Ramirez
asesor en sistemas
ant(a)aortiz.net
www.aortiz.net
www.visualcaja.com
www.progvisual.com




"Alejandro Mesa" escribió en el
mensaje news:
> Antonio Ortiz,
>
> Segun lo que comentas, algo no esta bien en ese esquema. Toda tabla debe
> tener una clave primaria, y sql server crea por defecto un indice
clustered
> por ella. En cambio, sql server no crea ningun indice para restricciones
de
> clave foranea y por ende se debe crear un indice por ellas para que sql
> server puede hacer uso de ellos cuando se hace un join usando estas
columnas
> o esa relacion. Algo se debe tener muy en cuenta cuando hablamos de
indices
> compuestos y esto es que el indice sera usado efectivamente solamente si
en
> la consulta aparece la columna mas a la izquierda en la definicion de la
> clave de ese indice, puesto que sql server solo guarda el histograma de
esa
> columna y la densidad de la composicion de esta columna y con el resto.
>
> Ejemplo:
>
> use northwind
> go
>
> create nonclustered index ix_nc_customers_country_city on
customers(country,
> city)
> go
>
> dbcc show_statistics (customers, ix_nc_customers_country_city)
> go
>
> set showplan_text on
> go
>
> select *
> from dbo.customers
> where country = 'France'
> go
>
> select *
> from dbo.customers
> where country = 'France' and city = 'Paris'
> go
>
> select customerid, country, city
> from dbo.customers
> where country = 'France' and city = 'Paris' and customerid = 'PARIS'
> go
>
> select customerid, country, city
> from dbo.customers
> where city = 'Paris'
> go
>
> set showplan_text on
> go
>
> drop index dbo.customers.ix_nc_customers_country_city
> go
>
>
> create nonclustered index ix_nc_customers_country_city on
customers(country,
> city)
> go
>
> Statistics for INDEX 'ix_nc_customers_country_city'.
> Updated Rows Rows Sampled Steps
> Density Average key length
>
> Nov 7 2005 8:46AM 91 91 21


0.0
> 37.582417
>
> (1 row(s) affected)
>
> All density Average Length Columns
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

> 4.7619049E-2 11.560439 Country
> 1.4492754E-2 27.582417 Country, City
> 1.0989011E-2 37.582417 Country, City,
CustomerID
>
> (3 row(s) affected)
>
> RANGE_HI_KEY RANGE_ROWS EQ_ROWS
> DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
>
> Argentina 0.0 3.0 0
> 0.0
> Austria 0.0 2.0 0
> 0.0
> Belgium 0.0 2.0 0
> 0.0
> Brazil 0.0 9.0 0
> 0.0
> Canada 0.0 3.0 0
> 0.0
> Denmark 0.0 2.0 0
> 0.0
> Finland 0.0 2.0 0
> 0.0
> France 0.0 11.0 0
> 0.0
> Germany 0.0 11.0 0
> 0.0
> Ireland 0.0 1.0 0
> 0.0
> Italy 0.0 3.0 0
> 0.0
> Mexico 0.0 5.0 0
> 0.0
> Norway 0.0 1.0 0
> 0.0
> Poland 0.0 1.0 0
> 0.0
> Portugal 0.0 2.0 0
> 0.0
> Spain 0.0 5.0 0
> 0.0
> Sweden 0.0 2.0 0
> 0.0
> Switzerland 0.0 2.0 0
> 0.0
> UK 0.0 7.0 0
> 0.0
> USA 0.0 13.0 0
> 0.0
> Venezuela 0.0 4.0 0
> 0.0
>
> (21 row(s) affected)
>
> DBCC execution completed. If DBCC printed error messages, contact your
> system administrator.
> StmtText
> -
>
> select *
> from dbo.customers
> where country = 'France'
>
> (1 row(s) affected)
>
> StmtText
>

> |--Bookmark Lookup(BOOKMARK:([Bmk1000]),
> OBJECT:([Northwind].[dbo].[Customers]))
> |--Index
>



Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
> SEEK:([Customers].[Country]=Convert([@1])) ORDERED FORWARD)
>
> (2 row(s) affected)
>
> StmtText


>
> select *
> from dbo.customers
> where country = 'France' and city = 'Paris'
>
> (1 row(s) affected)
>
> StmtText
>
>


> |--Bookmark Lookup(BOOKMARK:([Bmk1000]),
> OBJECT:([Northwind].[dbo].[Customers]))
> |--Index
>



Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
> SEEK:([Customers].[Country]=Convert([@1]) AND
> [Customers].[City]=Convert([@2])) ORDERED FORWARD)
>
> (2 row(s) affected)
>
> StmtText
>

-
>
> select customerid, country, city
> from dbo.customers
> where country = 'France' and city = 'Paris' and customerid = 'PARIS'
>
> (1 row(s) affected)
>
> StmtText
>
>

-
> |--Index
>



Seek(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
> SEEK:([Customers].[Country]=Convert([@1]) AND
> [Customers].[City]=Convert([@2]) AND
[Customers].[CustomerID]=Convert([@3]))
> ORDERED FORWARD)
>
> (1 row(s) affected)
>
> StmtText
>

-
>
> select customerid, country, city
> from dbo.customers
> where city = 'Paris'
>
> (1 row(s) affected)
>
> StmtText
>

> |--Index
>



Scan(OBJECT:([Northwind].[dbo].[Customers].[ix_nc_customers_country_city]),
> WHERE:([Customers].[City]=Convert([@1])))
>
> (1 row(s) affected)
>
> Vamos ahora a comentar sobre el plan de ejecucion escojido por sql


server
> para cada sentencia "select"
>
> Para la primera, sugunda y tercera sentencia "select", sql server


escojio
> hacer un "index seek" en el indice ].[ix_nc_customers_country_city],


esto
se
> debe a que las tres sentencias incluyen un argumento de busqueda por la
> columna mas a la izquierda en la clave del indice (country). Un caso
especial
> es la tercera sentencia, donde a diferencia con la primera y segunda,


sql
> server solo hace un "index seek" sin necesidad de hacer un "Bookmark
Lookup"
> y esto se debe a que el indice cubre todas las columnas que son
referenciadas
> en la sentencia (country, city y customerid) ya que el indice clustered


de
> esa tabla es por la columna "customerid" y como todos sabemos, sql


server
> referencia esta clave en todos los indices nonclustered de la tabla.


Este
> tipo de indice se conoce como "covering index". En cambio, para la


cuarta
> sentencia, sql server escoje hacer un "index scan" en ese indice en vez


de
un
> "index seek" y esto se debe principalmente a que en la consulta no


aparece
un
> argumento de busqueda por "country".
>
> Espero te haya servido de ayuda,
>
>
> AMB
>
> "Antonio Ortiz" wrote:
>
> > En la auditoria que estoy haciendo, encuentro la mayoria de las tablas
con
> > un unico indice compuesto, con hasta 8 campos. Sin embargo, en el
Analizador
> > de SQL, veo que algunas consultas se relacionan por alguna columna no
> > indexada, tanto en donde es (o debera) ser llave primaria y llave
> > secundaria. He procedido a indexar ambas columnas en las 2 tablas.
> >
> > Segun mi apreciacion, el indice compuesto, no sirve de mucho para


estas
> > consultas. Me estoy perdiendo algo que no estoy detectando o pueden
darme
> > algun comentario?
> >
> >
> > saludos a todos,
> >
> >
> > Antonio Ortiz
> > ant(a)aortiz.net
> > www.aortiz.net
> > www.progvisual.com
> >
> >
> >


Respuesta Responder a este mensaje
#5 Alejandro Mesa
07/11/2005 - 18:51 | Informe spam
Ademas de lo expuesto por Carlos, debes tener mucho cuidado cuando haces
"left join", osea, que usas "*= o =*, pues no existe un equivalente a los
"left - right join".

Ejemplo:

Seleccionar todos los clientes que no tienen una orden.

use northwind
go

select c.*
from dbo.customers as c left join dbo.orders as o
on c.customerid = o.customerid
where o.customerid is null

select c.*
from dbo.customers as c, dbo.orders as o
where c.customerid = o.customeris and o.customerid is null

La segunda expresion no es el equivalente de la primera, una columna no
puede ser NULL y a su vez ser igual al valor de otra columna.


AMB

"Carlos Sacristán" wrote:

En la consulta que envías el índice compuesto no sirve de nada porque no
es posible llegar al campo NoCliente sin haber pasado previamente por
NoProducto, NoCuenta y NoFolio

Entre hacer el join en el WHERE o en el JOIN no hay diferencias de
rendimiento. Yo prefiero la segunda opción porque me parece más claro,
pudiendo distinguir de un plumazo los criterios de búsqueda de los criterios
de combinación


Un saludo

-
"Sólo sé que no sé nada. " (Sócrates)

"Antonio Ortiz" escribió en el mensaje
news:
> mm, interesante, anoche me puse a buscar documentacion sobre indices
> compuestos y encontre lo que mencionas, el indice compuesto sera utilizado
> si se utiliza la columna mas a la izquierda.
>
> En las consultas que encontre no es asi, por ejemplo:
>
> Indice compuesto: ( NoProducto, NoCuenta, NoFolio, NoCliente,
> ClaveProveedor )
>
> Consulta: Select Movs.* From Clientes, Movs Where Clientes.NoCliente
> > Movs.NoCliente
> * Por cierto encontre consultas de este tipo, que ya las conocia, pero yo
> prefiero la notacion:
> Clientes.NoCliente = Movs.NoCliente
>
> Alguien podria opinar sobre las diferencias en funcionalidad entre ellas?
>
>
> gracias,
>
> Antonio Ortiz Ramirez
> asesor en sistemas
> ant(a)aortiz.net
> www.aortiz.net
> www.visualcaja.com
> www.progvisual.com
>
>
>
>
> "Alejandro Mesa" escribió en el
> mensaje news:
> > Antonio Ortiz,
> >
> > Segun lo que comentas, algo no esta bien en ese esquema. Toda tabla debe
> > tener una clave primaria, y sql server crea por defecto un indice
> clustered
> > por ella. En cambio, sql server no crea ningun indice para restricciones
> de
> > clave foranea y por ende se debe crear un indice por ellas para que sql
> > server puede hacer uso de ellos cuando se hace un join usando estas
> columnas
> > o esa relacion. Algo se debe tener muy en cuenta cuando hablamos de
> indices
> > compuestos y esto es que el indice sera usado efectivamente solamente si
> en
> > la consulta aparece la columna mas a la izquierda en la definicion de la
> > clave de ese indice, puesto que sql server solo guarda el histograma de
> esa
> > columna y la densidad de la composicion de esta columna y con el resto.
> >
> > Ejemplo:
> >
> > use northwind
> > go
> >
> > create nonclustered index ix_nc_customers_country_city on
> customers(country,
> > city)
> > go
> >
> > dbcc show_statistics (customers, ix_nc_customers_country_city)
> > go
> >
> > set showplan_text on
> > go
> >
> > select *
> > from dbo.customers
> > where country = 'France'
> > go
> >
> > select *
> > from dbo.customers
> > where country = 'France' and city = 'Paris'
> > go
> >
> > select customerid, country, city
> > from dbo.customers
> > where country = 'France' and city = 'Paris' and customerid = 'PARIS'
> > go
> >
> > select customerid, country, city
> > from dbo.customers
> > where city = 'Paris'
> > go
> >
> > set showplan_text on
> > go
> >
> > drop index dbo.customers.ix_nc_customers_country_city
> > go
> >
> >
> > create nonclustered index ix_nc_customers_country_city on
> customers(country,
> > city)
> > go
> >
> > Statistics for INDEX 'ix_nc_customers_country_city'.
> > Updated Rows Rows Sampled Steps
> > Density Average key length
> >
> > Nov 7 2005 8:46AM 91 91 21
0.0
> > 37.582417
> >
> > (1 row(s) affected)
> >
> > All density Average Length Columns
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
>
> > 4.7619049E-2 11.560439 Country
> > 1.4492754E-2 27.582417 Country, City
> > 1.0989011E-2 37.582417 Country, City,
> CustomerID
> >
> > (3 row(s) affected)
> >
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida