Este es un intento de mejorar el trabajo de Max Vernon . En su solución, sugiere usar 2 índices en la vista y un objeto de estadísticas.
El primer índice está agrupado, lo que en realidad es necesario ya que, a diferencia de un índice no agrupado en una tabla, se generará un error si se intenta la creación de un índice no agrupado en la vista sin tener primero un índice agrupado.
El segundo índice es un índice no agrupado, que se utiliza como índice detrás de la consulta. En la sección de comentarios de su respuesta, le pregunté qué pasaría si se usara un índice agrupado en lugar de un índice no agrupado.
El siguiente análisis intenta responder a esta pregunta.
Estoy usando exactamente el mismo código, excepto que no estoy creando un índice no agrupado en la vista.
Tampoco estoy creando un objeto de estadísticas. Si sigue y utiliza SQL Server Management Studio (SSMS) para ingresar el código a continuación, debe tener en cuenta que puede ver algunas líneas onduladas rojas, que parecen errores. Estos (probablemente) no son errores, pero involucran un problema con intellisense.
Puede desactivar intellisense o simplemente ignorar los errores y ejecutar los comandos. Deben completarse sin errores.
-- Create the test table that uses a computed column.
USE tempdb;
CREATE TABLE dbo.PersistedViewTest
(
PersistedViewTest_ID INT NOT NULL
CONSTRAINT PK_PersistedViewTest
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, SomeData VARCHAR(2000) NOT NULL
, TestComputedColumn AS (PersistedViewTest_ID - 1) PERSISTED
);
GO
-- Insert some test data into the table.
INSERT INTO dbo.PersistedViewTest (SomeData)
SELECT o.name + o1.name + o2.name
FROM sys.objects o
CROSS JOIN sys.objects o1
CROSS JOIN sys.objects o2;
GO
El siguiente plan de ejecución (sin vista de vista / índice) se produce después de ejecutar la siguiente consulta en la tabla:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Esto proporciona una línea de base para comparar. Observe que después de completar la consulta, se creó un objeto de estadísticas (_WA_Sys_00000003_1FCDBCEB). El objeto de estadísticas PK_PersistedViewTest se creó cuando se creó el índice de tabla en clúster.
A continuación, se crean la vista filtrada y el índice agrupado en esa vista:
-- Create filtered view on the computed column.
CREATE VIEW dbo.PersistedViewTest_View
WITH SCHEMABINDING
AS
SELECT PersistedViewTest_ID, SomeData, TestComputedColumn
FROM dbo.PersistedViewTest
WHERE TestComputedColumn < CONVERT(INT, 27);
GO
-- Create unique clustered index to persist the values, including the computed column.
CREATE UNIQUE CLUSTERED INDEX IX_PersistedViewTest
ON dbo.PersistedViewTest_View(PersistedViewTest_ID);
GO
Ahora, intentemos ejecutar la consulta nuevamente, pero esta vez en la vista:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
El nuevo plan de ejecución es ahora:
Si se cree en el nuevo plan, después de agregar la vista y el índice agrupado en esa vista, las estadísticas parecen indicar que el tiempo requerido para ejecutar la consulta ahora se ha duplicado. Además, observe que no se creó un nuevo objeto de estadísticas para admitir el nuevo índice después de que se ejecutó la consulta, que es diferente de la consulta en la tabla.
El plan de consulta aún sugiere que la creación de un índice no agrupado sería bastante útil para mejorar el rendimiento de la consulta. Entonces, ¿eso significa que se debe agregar un índice no agrupado a la vista antes de que se pueda obtener la mejora de rendimiento deseada? Hay una última cosa para probar. Modifique la consulta para usar la opción "WITH NOEXPAND":
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv WITH (NOEXPAND)
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Esto da como resultado el siguiente plan de consulta:
Este plan de ejecución se parece bastante al que se produjo con el índice no agrupado que figura en la respuesta de Max Vernon. Pero, este se hace con un índice menos (no agrupado) y un objeto de estadísticas menos.
Resulta que la opción NOEXPAND debe usarse con las versiones express y estándar de SQL Server para hacer un uso adecuado de una vista indizada. Paul White tiene un excelente artículo que expone los beneficios de usar la opción NOEXPAND. También recomienda que esta opción se use con la edición empresarial para garantizar que el optimizador utilice la garantía de unicidad proporcionada por los índices de vista.
El análisis anterior se realizó con la edición express de SQL Sever 2014. También lo probé con la edición de desarrollador de SQL Server 2016. La opción NOEXPAND no parece ser necesaria con la edición de desarrollo para lograr las mejoras de rendimiento, pero todavía se recomienda .
Hace menos de 5 meses, Microsoft hizo las ediciones para desarrolladores gratuitas . La licencia restringe el uso solo al desarrollo, lo que significa que la base de datos no se puede usar en un entorno de producción. Entonces, si ha estado buscando probar tablas optimizadas de memoria, cifrado, R, etc., entonces ya no tiene la excusa sin licencia. Lo instalé con éxito en mi computadora hace unos días junto con SQL Server 2014 Express sin problemas.
WHERE (sintMarketID = 2 AND strType = 'CARD' AND strTier1 LIKE 'GG%')
.