Desempeño en SQL (No 2)

Escrito por Administrator. Publicado en artículos técnicos

Bienvenido a la segunda entrega de nuestra serie de artículos Desempeño en SQL.  Pretendemos crear un conjunto de consejos fáciles de implementar, prácticos y sencillos para mejorar el desempeño de sus consultas SQL en Microsoft SQL-Server 2005 y superior.  Si desea leer las entregas anteriores, visite nuestra sección de Artículos Técnicos

No sea indulgente con las consultas anidadas

Las vistas en SQL no son tablas.  Esto parece una tautología: por supuesto todos sabemos que no son tables.


El problema es que las vistas parecen tablas, responden como tablas y producen resultados como tablas, y por eso tendemos a pensar que es igual usar una tabla o una vista en una sentencia compuesta.


Pero no es cierto.  Cuando se crea una consulta que mezcla varias vistas (usando sentencias JOIN) o bien que usa consultas anidadas basadas en otras vistas, se crea un plan de ejecución sumamente complejo, y eso redunda en que el desempeño es inconsistente y generalmente problemático.

Veamos los efectos que esto tiene en el desempeño.  Aquí definimos un par de consultas sencillas:

CREATE VIEW dbo.SalesInfoView
AS
    SELECT  soh.SalesOrderID,
            soh.OrderDate,
            soh.SalesPersonID,
            soh.PurchaseOrderNumber,
            soh.AccountNumber,
            a.City AS ShippingCity
    FROM    Sales.SalesOrderHeader AS soh
            JOIN Person.Address AS a
            ON soh.ShipToAddressID = a.AddressID ;
 
 
CREATE VIEW dbo.SalesDetailsView
AS
    SELECT  sod.SalesOrderID,
            sod.SalesOrderDetailID,
            sod.OrderQty,
            sod.UnitPrice
    FROM    Sales.SalesOrderDetail AS sod ;
 
 
CREATE VIEW dbo.CombinedSalesInfoView
AS
    SELECT  si.SalesPersonID,
            si.ShippingCity,
            si.OrderDate,
            si.PurchaseOrderNumber,
            si.AccountNumber,
            sd.OrderQty,
            sd.UnitPrice
    FROM    dbo.SalesInfoView AS si
            JOIN dbo.SalesDetailsView AS sd
            ON si.SalesOrderID = sd.SalesOrderID ;

Ahora, creadas estas vistas, ejecutemos esta consulta

SELECT OrderDate FROM dbo.CombinedSalesInfoView WHERE SalesPersonID = 277

Esta consulta ejecuta en alrededor de 155 milisegundos, y realiza 965 lecturas contra las dos tablas.  Este es el plan de ejecución creado por el analizador de consultas:

¿Que ocurre cuando usamos simplemente la tabla original en lugar de la vista?

SELECT OrderDate FROM dbo.SalesOrderHeader WHERE SalesPersonID = 277

En este caso, la consulta ejecuta 685 lecturas y toma tan solo 3 milisegundos.  El plan de ejecución de la consulta nos revela la causa de esta diferencia tan dramática:

Lo que ocurre es que el analizador de consultas no puede simplemente eliminar una de las tablas que conforma la consulta cuando se usa la vista.  Esto provoca lecturas adicionales al índice de la segunda tabla, aunque en realidad su contenido no se utiliza.

De modo que es preferible realizar consultas directamente sobre las tablas en lugar de una vista compleja, siempre y cuando se trate de obtener información que se puede derivar de una de las tablas.

Revise las sentencias SELECT de sus sistemas, y si descubre que se usan solamente para obtener información de algunas columnas, evalue la posibilidad de simplificar el código obteniendo dichos campos directamente de las tablas base.

 

 

  • Paquetes WEB
  • Aplicaciones
  • Apoyo Técnico
  • Sistemas de Pesaje