Cuando crea un índice en una columna o número de columnas en MS SQL Server (estoy usando la versión 2005), puede especificar que el índice en cada columna sea ascendente o descendente. Me cuesta entender por qué esta elección está aquí. Usando técnicas de clasificación binarias, ¿no sería una búsqueda igual de rápida en ambos sentidos? ¿Qué diferencia hace qué orden elijo?Índices de SQL Server: ascendente o descendente, ¿qué diferencia hace?
Respuesta
Esto es importante sobre todo cuando se utiliza con índices compuestos:
CREATE INDEX ix_index ON mytable (col1, col2 DESC);
se puede utilizar para cualquiera de los dos:
SELECT *
FROM mytable
ORDER BY
col1, col2 DESC
o:
SELECT *
FROM mytable
ORDER BY
col1 DESC, col2
, pero no para:
SELECT *
FROM mytable
ORDER BY
col1, col2
Un índice en una sola columna se puede usar de manera eficiente para ordenar en ambos sentidos.
Ver el artículo en mi blog para más detalles:
Actualización:
De hecho, esto se puede importar ni un solo índice de la columna, aunque no es tan obvio.
Imagínese un índice en una columna de una tabla agrupado:
valoresCREATE TABLE mytable (
pk INT NOT NULL PRIMARY KEY,
col1 INT NOT NULL
)
CREATE INDEX ix_mytable_col1 ON mytable (col1)
El índice en col1
mantiene ordenada de col1
junto con las referencias a las filas.
Dado que la tabla está agrupada, las referencias a filas son en realidad los valores de pk
. También se ordenan dentro de cada valor de col1
.
Esto significa que eso deja de índice son realmente ordenada en (col1, pk)
, y esta consulta:
SELECT col1, pk
FROM mytable
ORDER BY
col1, pk
necesidades sin clasificación.
si creamos el índice de la siguiente manera:
CREATE INDEX ix_mytable_col1_desc ON mytable (col1 DESC)
, descendente continuación se ordenarán los valores de col1
, pero los valores de pk
dentro de cada valor de col1
se ordenan ascendente.
Esto significa que la siguiente consulta:
SELECT col1, pk
FROM mytable
ORDER BY
col1, pk DESC
puede ser servido por ix_mytable_col1_desc
pero no por ix_mytable_col1
.
En otras palabras, las columnas que constituyen un CLUSTERED INDEX
en cualquier tabla son siempre las columnas finales de cualquier otro índice en esa tabla.
El orden de clasificación importa cuando desea recuperar muchos datos ordenados, no registros individuales.
Tenga en cuenta que (como sugiere con su pregunta) el orden de clasificación suele ser mucho menos significativo que las columnas que indexa (el sistema puede leer el índice en reversa si el orden es opuesto a lo que desea). Raramente le doy un orden de clasificación de índice a cualquier pensamiento, mientras que agonizo sobre las columnas cubiertas por el índice.
@Quassnoi proporciona un great example de cuando hace asunto.
Para un verdadero índice de columna individual, no hace mucha diferencia desde el punto de vista del Optimizador de consultas.
Para la definición de la tabla
CREATE TABLE T1([ID] [int] IDENTITY NOT NULL,
[Filler] [char](8000) NULL,
PRIMARY KEY CLUSTERED ([ID] ASC))
La consulta
SELECT TOP 10 *
FROM T1
ORDER BY ID DESC
Utiliza una exploración ordenada con el sentido de la exploración BACKWARD
como puede verse en el plan de ejecución. Sin embargo, hay una ligera diferencia en que actualmente solo los escaneos FORWARD
se pueden paralelizar.
Sin embargo se puede hacer una gran diferencia en términos de fragmentación lógica. Si el índice se crea con teclas que descienden, pero las nuevas filas se anexan con valores de clave ascendentes, puede terminar con cada página fuera de orden lógico. Esto puede afectar seriamente el tamaño de las lecturas de E/S al escanear la tabla y no está en la memoria caché.
ver resultados de la fragmentación
avg_fragmentation avg_fragment
name page_count _in_percent fragment_count _size_in_pages
------ ------------ ------------------- ---------------- ---------------
T1 1000 0.4 5 200
T2 1000 99.9 1000 1
para el script de abajo
/*Uses T1 definition from above*/
SET NOCOUNT ON;
CREATE TABLE T2([ID] [int] IDENTITY NOT NULL,
[Filler] [char](8000) NULL,
PRIMARY KEY CLUSTERED ([ID] DESC))
BEGIN TRAN
GO
INSERT INTO T1 DEFAULT VALUES
GO 1000
INSERT INTO T2 DEFAULT VALUES
GO 1000
COMMIT
SELECT object_name(object_id) AS name,
page_count,
avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages
FROM
sys.dm_db_index_physical_stats(db_id(), object_id('T1'), 1, NULL, 'DETAILED')
WHERE index_level = 0
UNION ALL
SELECT object_name(object_id) AS name,
page_count,
avg_fragmentation_in_percent,
fragment_count,
avg_fragment_size_in_pages
FROM
sys.dm_db_index_physical_stats(db_id(), object_id('T2'), 1, NULL, 'DETAILED')
WHERE index_level = 0
Es posible usar la pestaña de resultados espaciales para verificar la suposición de que esto se debe a las páginas posteriores han ascendente valores clave en ambos casos.
SELECT page_id,
[ID],
geometry::Point(page_id, [ID], 0).STBuffer(4)
FROM T1
CROSS APPLY sys.fn_PhysLocCracker(%% physloc %%)
UNION ALL
SELECT page_id,
[ID],
geometry::Point(page_id, [ID], 0).STBuffer(4)
FROM T2
CROSS APPLY sys.fn_PhysLocCracker(%% physloc %%)
Gracias Martin por este gran TIP, esto realmente me ayudó en las consultas de rango – TheGameiswar
Me pregunto si tengo un índice descendente, luego selecciono mycolumn de mytable donde indexed_column = \ @myvalue es más rápido cuando \ @myvalue está más cerca del valor máximo posible que en el caso cuando \ @myvalue está cerrado al valor mínimo posible. –
@LajosArpad ¿por qué sería uno más rápido? B árboles son árboles equilibrados.La profundidad del árbol es la misma para ambos. –
- 1. Clave principal ascendente vs descendente
- 2. Programación descendente y ascendente
- 3. Índices agrupados SQL Server
- 4. ¿Qué hace xp_qv en SQL Server?
- 5. SQL Server no agrupado diseño de índices
- 6. Índices de SQL Server: ¿qué columnas incluir en el índice?
- 7. ¿Qué hace OBJECT_ID en SQL Server?
- 8. SQL Server Tabla de sinónimos con índices
- 9. Vista ascendente/descendente de animaciones de Android adecuada
- 10. conjunto de consultas django order_by, ascendente y descendente
- 11. SQL Server 2005 - ¿Con qué frecuencia debe reconstruir los índices?
- 12. Intercalaciones en índices en SQL Server
- 13. ¿Dinámicamente nombrar índices en SQL Server 2005?
- 14. ¿Qué hace "Crear estadísticas" en SQL Server 2005?
- 15. Cómo script de índices, claves, claves externas en SQL Server
- 16. sql server delete ralentizado drásticamente por los índices
- 17. Índices alineados por partición en SQL Server 2008
- 18. sql server: crear índices en claves externas donde sea necesario
- 19. ¿Todas las versiones de SQL Server reconstruyen índices automáticamente o tienen un criterio de reconstrucción predeterminado?
- 20. SQL Server DELETE es más lento con los índices
- 21. NSArray en orden descendente
- 22. Cómo administrar varios índices superpuestos en SQL Server 2005
- 23. Java Array Orden descendente?
- 24. Sniffing de parámetros (o Spoofing) en SQL Server
- 25. SQL Server Index ¿Qué debería agruparse?
- 26. transacción Sql - SQL Server o C#?
- 27. PostgreSQL o MS SQL Server?
- 28. ¿Qué son los índices de cobertura y las consultas cubiertas en SQL Server?
- 29. ¿Con qué frecuencia deberían reconstruirse los índices en nuestra base de datos SQL Server?
- 30. ¿Qué significa en sentido ascendente en nginx?
Cuando dice "no para ..." Qué quiere decir no lo puedo trabajar o el rendimiento será horrible? –
Quiero decir que el índice no se usará para la consulta. La consulta en sí funcionará, por supuesto, pero el rendimiento será pobre. – Quassnoi
En la primera sección, ¿no debería el segundo ejemplo decir "PEDIDO POR col1 DESC, col2 DESC"? –