Solucionar problemas de errores DBCC en vistas indizadas
Puede utilizar DBCC CHECKDB y DBCC CHECKTABLE para comprobar si una vista indizada contiene las mismas filas que se encuentran calculando la vista desde las tablas base. Si DBCC devuelve los errores 8907 u 8908, que indican que la vista almacenada no es idéntica a la calculada, tenga en cuenta lo siguiente para resolver el problema.
¿La definición de la vista incluye sugerencias?
SQL Server 2000 permite crear vistas indizadas que contienen sugerencias de tabla como NOLOCK. En ocasiones, esto puede dañar la vista indizada. Si la vista incluye sugerencias de tabla, quítela, edite su definición para eliminarlas y vuelva a crearla. A continuación, vuelva a crear el índice en la vista.
¿La vista indizada calcula un agregado SUM con valores del tipo float o real?
Si es el caso, ¿las diferencias entre la vista indizada y la calculada se encuentran únicamente en la columna de agregados y se trata de diferencias mínimas para las filas almacenadas y calculadas correspondientes? Si no son significativas, teniendo en cuenta los datos y la aplicación, no se requiere ninguna acción correctora.
Si son significativas, quite el índice de la vista y vuelva a crearlo. En este caso, los daños se deben probablemente a la naturaleza aproximada de la aritmética de coma flotante. En ocasiones, el orden en el que se agregan los números durante el mantenimiento de las vistas indizadas puede afectar ligeramente al resultado final. Para obtener más información acerca de cómo utilizar los tipos de datos aproximados, vea Usar datos decimal, float y real. Si la aplicación usa tipos de coma flotante, pero se pueden cumplir los requisitos con un tipo de decimal exacto (numeric, money o decimal), considere la posibilidad de usar numeric en una versión revisada de la vista indizada.
Si la vista indizada no incluye un agregado con valores del tipo float o real y recibe los errores 8907 u 8708, quite el índice de la vista y vuelva a crearlo.
No utilice ALTER INDEX REBUILD para intentar eliminar las diferencias entre la vista almacenada y la calculada, pues ALTER INDEX REBUILD no vuelve a calcular la vista antes de volver a generar el índice.
Después de volver a generar el índice en la vista, ejecute DBCC CHECKTABLE en la misma para comprobar que no queda ninguna diferencia. De lo contrario, puede que se trate de un error de hardware o de otro tipo.
¿Cómo se puede determinar si las diferencias entre las vistas indizadas y las calculadas son significativas?
Si las diferencias entre la vista indizada y la vista calculada no son pequeñas diferencias en un agregado SUM de un valor float o real , probablemente se trata de diferencias significativas. En ese caso, quite el índice de la vista y vuelva a crearlo. Si sólo existe una diferencia entre las vistas en un agregado SUM de un valor float o real y la vista es pequeña, compare las vistas indizada y calculada de forma visual y decida si las diferencias son significativas. En el caso de una vista ViewName, haga lo siguiente para obtener los valores calculados y almacenados:
SELECT * FROM ViewName OPTION(EXPAND VIEWS) -- Get calculated view.
SELECT * FROM ViewName WITH(NOEXPAND) -- Get stored view.
Puede resultar útil consultar la diferencia absoluta o porcentual de las filas distintas del mismo grupo de una vista agregada para determinar si las diferencias son significativas. Por ejemplo, en el script siguiente se muestra cómo comparar una vista indizada y una calculada que muestran pequeñas diferencias. El script muestra pares de filas del mismo grupo con sumas almacenadas y calculadas distintas.
IF OBJECT_ID('v') IS NOT NULL DROP VIEW v
IF OBJECT_ID('t') IS NOT NULL DROP TABLE t
go
CREATE TABLE t
(id int NOT NULL PRIMARY KEY,
a int NOT NULL,
b float(53) NOT NULL)
GO
CREATE VIEW v WITH SCHEMABINDING AS
SELECT a, SUM(b) AS sum_b, COUNT_BIG(*) AS c
FROM dbo.t
GROUP BY a
GO
CREATE UNIQUE CLUSTERED INDEX idx ON v(a)
GO
INSERT t VALUES(1, 1,1.0e1)
INSERT t VALUES(2, 1,1.0e2)
INSERT t VALUES(3, 2, 1.0e0)
INSERT t VALUES(4, 2, 5.0e-17)
INSERT t VALUES(5, 2, 5.0e-17)
INSERT t VALUES(6, 2, 5.0e-17)
GO
DELETE FROM t WHERE id=3
GO
DBCC CHECKTABLE ('v')
GO
-- Show the groups that have different SUMs,
-- and the difference between the sums.
SELECT *, v1.sum_b - v2.sum_b AS sum_b_diff
FROM (SELECT * FROM v WITH (NOEXPAND)) AS v1,
(SELECT * FROM v) AS v2
WHERE v1.a=v2.a
AND (v1.sum_b - v2.sum_b) <> 0
OPTION(EXPAND VIEWS)
GO
El resultado muestra que sólo un grupo tiene un valor SUM distinto, y que la diferencia sum_b_diff es muy pequeña.
Vea también