SQL Server 2008 - Buscando Stored Procedures que no están en el caché

Con el query que se publica a continuación se puede obtener una lista de Stored Procedures que no están en el cache, lo cual podría posibilitar investigar luego si esos S.P. que no están en el cache son realmente utilizados o no.

Atención, nunca borre o elimine un stored procedure basandose en este query, ya que este query indica solamente si el sp está en el cache, lo cual no significa necesariamente que no se utiliza, por caso si un S.P. tiene las sentencias RECOMPILE, nunca jamás aparecerá en el cache a pesar de ser plenamente utilizado.

Y recuerde que en vez de eliminar un S.P. debería renombrarlo con algún prefijo que identifique claramente a los SPs a investigar en el entorno de testing y luego hacer las pruebas correspondientes en entornos de testing y de pruebas para ver si ese S.P. es usado o no. Y obviamente, luego de todas esas pruebas y como medida de seguridad adicional, antes de borrar un S.P. en producción se debe guardar un script con toda la lógica.

Dicho lo anterior, veamos los scripts:
-- Obtengo una lista de SPs en la base de datos (SQL 2005 and 2008)
  SELECT p.name AS 'SP Name', p.create_date, p.modify_date      
  FROM sys.procedures AS p
  WHERE p.is_ms_shipped = 0
  ORDER BY p.name;


  -- Obtener una lista de SPs posiblemente no usados (SQL 2008 solamente)
  SELECT p.name AS 'SP Name'        
  FROM sys.procedures AS p
  WHERE p.is_ms_shipped = 0

  EXCEPT

  SELECT p.name AS 'SP Name'        -- Lista de SPs en la base actual
  FROM sys.procedures AS p          -- que están en el procedure cache
  INNER JOIN sys.dm_exec_procedure_stats AS qs
  ON p.object_id = qs.object_id
  WHERE p.is_ms_shipped = 0;
Adicionalmente usted puede usar el siguiente query (solamente SQL Server 2008)
para determinar las dependencias de un objeto.
SELECT referencing_schema_name, referencing_entity_name
FROM sys.dm_sql_referencing_entities (‘Person.Address’, 'OBJECT');


Estos consejos son dados "AS IS" "TAL COMO ESTÁN", no doy ni concedo explicita o implicitamente
garantía alguna acerca de estos scripts, queries y consejos, ni de su funcionalidad ni utilidad
y su uso queda bajo la exclusiva responsabilidad de un Administrador de Bases de Datos competente
y experimentado, toda responsabilidad por daños alguno o el mal uso de los mismos queda bajo la
responsabilidad exclusiva de dicho administrador y se da por entendido que las bases de Datos
SQL Server deben ser administradas por profesionales expertos en dicha tecnología.
No me hago cargo de modo alguno por daños en datos, sistemas y servidores o 
similes por el uso de este o cualquier otro artículo de este blog.

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Intersect, Except, Union, All and Any - David Poole

David Poole en SQLServerCentral hace una revisión de algunos nuevos comandos en SQL Server 2008, por caso:

INTERSECT
EXCEPT
ALL
ANY
ALL y ANY no son nuevos, pero INTERSECT y EXCEPT son nuevos.

INTERSECT, EXCEPT and UNION

Para experimentar con esos comandos David decidió ver dos conjuntos de valores para CustomerID.

Customers (Clientes) en sales territory 10 (United Kingdom)
(pedidos) Sales orders de July 2004, el cual es el último mes de pedidos en Adventureworks
La mejor manera de ver que hacen estos dos comandos es comparar los datos en los diagramas.
redicate Illustration Description
EXCEPT Customers (clientes) de UK que no compraron en Julio 2004
INTERSECT Customers (clientes) de UK
AND (y) que compraron algo en Julio 2004
UNION Customers (clientes) de UK
OR (o) que hicieron una compra en Julio 2004

Diferentes formas de escribir un query con EXCEPT.

Si bien nunca usé EXCEPT antes yo he obtenido los mismos resultados por métodos tradicionales, hay muchas formas de hacer lo mismo, por ejemplo:
LEFT JOIN
Este query trae los resultados requeridos.
SELECT C.CustomerID
   FROM Sales.Customer AS C
    LEFT JOIN Sales.SalesOrderHeader AS OH
    ON C.CustomerID = OH.CustomerID
    AND OrderDate>='2004-07-01'
   WHERE OH.CustomerID IS NULL
   AND C.TerritoryID=10
WHERE CustomerID NOT IN(…)
Buscando la eficiencia, otra forma de hacer lo mismo.

SELECT CustomerID
   FROM Sales.Customer
   WHERE TerritoryID=10
   AND CustomerID NOT IN(
    SELECT customerid
    FROM  Sales.SalesOrderHeader
    WHERE OrderDate>='2004-07-01'
   )

EXCEPT

Finalmente usando el nuevo comando Except.
SELECT CustomerID
   FROM Sales.Customer
   WHERE TerritoryID=10
    EXCEPT
   SELECT customerid
   FROM Sales.SalesOrderHeader
   WHERE OrderDate>='2004-07-01'

Diferentes maneras de escribir un query tipo INTERSECT

Tres ejemplos:
INNER JOIN
Como un cliente puede tener mas de un pedido tengo que hacer una lista con distinct para los valores del customerid, veamos dos enfoques para lo mismo.

As any customer can have more than one order I am going to have to make a distinct list of CustomerID values. I decided to try a couple of approaches.
SELECT DISTINCT C.CustomerID
   FROM Sales.Customer AS C
    INNER JOIN Sales.SalesOrderHeader AS OH
    ON C.CustomerID = OH.CustomerID
   WHERE
    C.TerritoryID=10
    AND OH.OrderDate>='2004-07-01'

SELECT C.CustomerID
   FROM Sales.Customer AS C
    INNER JOIN (SELECT DISTINCT CustomerID FROM Sales.SalesOrderHeader WHERE OrderDate>='2004-07-01'
   )AS OH
    ON C.CustomerID = OH.CustomerID
   WHERE C.TerritoryID=10
WHERE CustomerID IN(…)
SELECT CustomerID
   FROM Sales.Customer
   WHERE TerritoryID=10
   AND CustomerID IN(
    SELECT customerid
    FROM  Sales.SalesOrderHeader
    WHERE OrderDate>='2004-07-01'
   )
INTERSECT
Finalmente un intersect.
SELECT CustomerID
   FROM Sales.Customer
   WHERE TerritoryID=10
    INTERSECT
   SELECT customerid
   FROM Sales.SalesOrderHeader
   WHERE OrderDate>='2004-07-01'
The ANY and ALL Predicate
ANY and ALL are predicates I have never needed to use.

ANY

Los dos queries nos ofrecen los mismos resultados y el mismo plan de ejecución:
SELECT *
   FROM Sales.SalesPerson
   WHERE TerritoryID = ANY(
    SELECT TerritoryID FROM Sales.SalesTerritory WHERE CountryRegionCode='US'
   )

SELECT *
   FROM Sales.SalesPerson
   WHERE TerritoryID IN(
    SELECT TerritoryID FROM Sales.SalesTerritory WHERE CountryRegionCode='US'
   )
   
ALL
All permite una comparación contra todos los valores en una lista de un select, por caso estos dos queries son idénticos:

SELECT *
   FROM Sales.SalesOrderHeader
   WHERE TotalDue > ALL(SELECT TotalDue FROM Sales.TopSales)
   ORDER BY Sales.TotalDue DESC 

SELECT *
   FROM Sales.SalesOrderHeader
   WHERE TotalDue > (SELECT MAX(TotalDue) FROM Sales.TopSales)
   ORDER BY Sales.TotalDue DESC 
La página original se encuentra en:

http://www.sqlservercentral.com/articles/T-SQL/67545/


Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...