Smallint <> Int
Por si no lo sabían, mi formación profesional es de Sistemas. Entre las cosas que me dan de comer, se encuentra el saber programar en SQL Server 2000. Y si ustedes también lo hacen, sabrán como yo que por muy bonito que pueda ser programado un query, stored procedure, función, o cualquier cosa, siempre resulta importante colocar el rendmiento, o performance, por delante de cualquier diseño de base de datos o query que nos hayan requerido.
La idea entonces es ir compartiendo con ustedes esos conocimientos que he adquirido con el pasar de los años, y que definitivamente he comprobado que sirven. De cuando en cuando estaré por aquí aconsejándolos. Si quieren que trate algún tema en particular, pues bienvenido, para eso estamos.
Hoy nos concentraremos un poco en la importancia de los tipos de datos.
Digamos que tenemos dos tablas, Cliente y Pedido. Estas tablas tienen la siguiente estructura (coloco la sentencia create, para que se pueda apreciar mejor):
CREATE TABLE [Pedido] (
[PedidoID] [int] IDENTITY (1, 1) NOT NULL ,
[ClienteID] [int] NOT NULL ,
[EmpleadoID] [int] NOT NULL ,
[FechaPedido] [datetime] NULL ,
[FechaRequerida] [datetime] NULL ,
[FechaEmbarque] [datetime] NULL ,
[ModoEntrega] [int] NULL
) ON [PRIMARY]
GO
CREATE TABLE [Cliente] (
[ClienteID] [smallint],
[Compania] [nvarchar] (40) NULL,
[Contacto] [nvarchar] (30) NULL,
[Direccion] [nvarchar] (60) NULL,
[Ciudad] [nvarchar] (15) NULL,
[Region] [nvarchar] (15) NULL,
[Pais] [nvarchar] (15) NULL,
[Telefono] [nvarchar] (24) NULL
) ON [PRIMARY]
GO
Y digamos que nos solicitan el típico query en el que se puedan listar los pedidos por cliente. Un query que cumpla con el requerimiento puede ser realizado de la siguiente manera (la más simple vamos a colocarla aquí):
select Compania, Contacto, FechaPedido, FechaEmbarque
from Cliente
join Pedido
on Pedido.ClienteID = Cliente.ClienteID
Y nos sentimos contentos porque el jefe nos felicitó por tener el query en menos de 5 minutos. Cuando lo ejecutan en producción, el usuario se queja que el query se está demorando mucho. ¿Qué falló?
Simple, amigo lector. El tema es de tipos de datos. Si notas en las tablas, la columna ClienteID de la tabla Cliente tiene tipo de datos smallint. En la tabla Pedido, la columna con la que hacemos el join ClienteID (usualmente la clave foránea), tiene tipo de datos int. Si cambiamos ésta última y le ponemos el mismo tipo de datos, el query aumentará su velocidad enormemente. He comprobado en algunas circunstancias, que las ejecuciones se optimizan hasta en un 80%.
¿Por qué? El SQL tiene un motor muy bueno, pero cuando se hacen joins, se evalúan varias cosas. Primero el tipo de datos. Si las columnas son de tipos de datos diferentes, se invalida el join, e internamente se efectúa un convert. Esta sentencia de por sí ya provoca que el motor no tome el índice adecuado, al dejar de ser la consulta SARGable, lo que vuelve el query improductivo y de bajo rendimiento.
Espero que les sea de mucha utilidad.
Nuestros lectores también disfrutaron de:
- Problemas con cajeros automáticos
- La vida de un Ingeniero…
- Ebay compra Skype
- Yeyito: Siguiente generación en comunicación???
- Guerra de cerveza!



3 Comentarios para “Smallint <> Int”
y cuando no es tan trivial el cambiar el tipo de dato de una tabla? si es una tabla en producción, con millones de registros?
SQLSERVER permite crear índices basados en una función? (no simplemente basados en valor)
Por eso me quedo con Oracle
…
Yo apenas si rasguño algo de MySql que me tocó aprender a la fuerza cuando empecé a desarrollar el software que hoy uso para controlar mi cybercafé (y que en esta semana ya le voy a dar de baja
para empezar a usar el famoso taiwanés GetoManager).
Un buen tip, pero que me pareció bastante obvio. Si tengos dos tablas y en las dos tengo el mismo campo me parece que obviamente crearé ese campo con el mismo tipo de datos en los dos lugares. En otras palabras:¿si lo creé como INT en una tabla ¿por qué habría de crearlo como SMALLINT en otra tabla?
Yop, creo que el SQL Server 2005 ya trae dicha funcionalidad, al permitir índices sobre columnas calculadas. Ya voy a confirmar.
Phantom, en este “suc-mundú” de los sistemas, uno se encuentra con cada cosa…