Lorsque vous créez un index sur une colonne ou un nombre de colonnes dans MS SQL Server (j'utilise la version 2005), vous pouvez spécifier que l'index de chaque colonne soit ascendant ou descendant. J'ai du mal à comprendre pourquoi ce choix est encore là. En utilisant des techniques de tri binaire, une recherche ne serait-elle pas aussi rapide de toute façon? Quelle différence cela fait-il quel ordre je choisis?Index SQL Server - croissant ou décroissant, quelle différence cela fait-il?
Répondre
Ce point est important surtout quand il est utilisé avec des indices composites:
CREATE INDEX ix_index ON mytable (col1, col2 DESC);
peuvent être utilisés soit pour:
SELECT *
FROM mytable
ORDER BY
col1, col2 DESC
ou:
SELECT *
FROM mytable
ORDER BY
col1 DESC, col2
, mais pas pour:
SELECT *
FROM mytable
ORDER BY
col1, col2
Un index sur une seule colonne peut être utilisé efficacement pour le tri dans les deux sens.
Voir l'article dans mon blog pour plus de détails:
Mise à jour:
En fait, cela peut compter, même pour un indice de colonne unique, bien que ce n'est pas tellement évident.
Imaginez un index sur une colonne d'une table en cluster:
CREATE TABLE mytable (
pk INT NOT NULL PRIMARY KEY,
col1 INT NOT NULL
)
CREATE INDEX ix_mytable_col1 ON mytable (col1)
L'index sur col1
continue des valeurs ordonnées de col1
ainsi que les références à des lignes.
Étant donné que la table est mise en cluster, les références aux lignes correspondent en fait aux valeurs de pk
. Ils sont également classés dans chaque valeur de col1
.
Cela signifie que que les feuilles de l'indice sont effectivement commandés sur (col1, pk)
, et cette requête:
SELECT col1, pk
FROM mytable
ORDER BY
col1, pk
besoins sans tri.
Si nous créons l'index comme suit:
CREATE INDEX ix_mytable_col1_desc ON mytable (col1 DESC)
, les valeurs de col1
seront triées descendant, mais les valeurs de pk
dans chaque valeur de col1
seront triés croissant.
Cela signifie que la requête suivante:
SELECT col1, pk
FROM mytable
ORDER BY
col1, pk DESC
peut être servi par ix_mytable_col1_desc
mais pas par ix_mytable_col1
. En d'autres termes, les colonnes qui constituent CLUSTERED INDEX
sur n'importe quelle table sont toujours les colonnes finales de tout autre index de cette table.
L'ordre de tri est important lorsque vous souhaitez récupérer de nombreuses données triées, et non des enregistrements individuels. Notez que (comme vous le suggérez avec votre question) l'ordre de tri est généralement beaucoup moins important que les colonnes que vous indexez (le système peut lire l'index à l'envers si l'ordre est contraire à ce qu'il veut). Je donne rarement une idée à l'ordre de tri de l'index, alors que je agonise sur les colonnes couvertes par l'index.
@Quassnoi fournit un great example de quand fait matière.
Pour un véritable index de colonne unique, cela ne fait pas de grande différence du point de vue de l'Optimiseur de requête.
Pour la définition de table
CREATE TABLE T1([ID] [int] IDENTITY NOT NULL,
[Filler] [char](8000) NULL,
PRIMARY KEY CLUSTERED ([ID] ASC))
Le Query
SELECT TOP 10 *
FROM T1
ORDER BY ID DESC
Utilise une analyse commandée avec la direction de balayage BACKWARD
comme on peut le voir dans le plan d'exécution. Il existe cependant une légère différence en ce sens que seuls les balayages FORWARD
peuvent être parallélisés.
Cependant il peut faire une grande différence en termes de fragmentation logique. Si l'index est créé avec des clés décroissantes mais que de nouvelles lignes sont ajoutées avec des valeurs de clé croissantes, vous pouvez vous retrouver avec chaque page hors de l'ordre logique. Cela peut gravement affecter la taille des lectures d'E/S lors de l'analyse de la table et n'est pas dans le cache.
Voir la fragmentation résulte
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
pour le script ci-dessous
/*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
Il est possible d'utiliser l'onglet résultats spatiaux afin de vérifier la supposition que ce soit parce que les pages suivantes ont par ordre croissant des valeurs clés les deux cas.
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 %%)
Merci Martin pour cet excellent TIP, cela m'a vraiment aidé dans les requêtes de classement – TheGameiswar
Je me demande si j'ai un index descendant, puis sélectionnez mycolumn depuis mytable où indexed_column = \ @myvalue est plus rapide quand \ @myvalue est plus proche de la valeur maximale possible que dans le cas où \ @myvalue est fermé à la valeur minimale possible. –
@LajosArpad pourquoi serait-on plus rapide? Les arbres B sont des arbres équilibrés.La profondeur de l'arbre est la même pour les deux. –
- 1. Clé primaire Croissant et décroissant
- 2. Quelle est la différence entre créer un index UNIQUE comme "index" ou comme "contrainte" dans SQL Server?
- 3. SQLite3: programatically déterminer si une colonne est triée par ordre croissant ou décroissant
- 4. SQL Server: index clusterisé sur datetime, ASC ou DESC
- 5. SQL Server et index
- 6. Existe-t-il une différence entre id, date ou date, id index dans SQL Server
- 7. Index SQL Server
- 8. Syntaxe de table SQL Server avec index
- 9. SQL Server - Tables partitionnées et index clusterisé?
- 10. SQL Server: Index normal par rapport à l'index Fulltext
- 11. Index SQL Server pour les curseurs
- 12. Index varchar sur MS SQL Server 2005
- 13. Différence entre sp_spaceused et DataLength SQL Server
- 14. SQL Server 2005 - À quelle fréquence devez-vous reconstruire les index?
- 15. IE6 Z-Index Différence entre 2 serveurs
- 16. Quelle est la différence entre type et xtype dans les vues système dans SQL Server?
- 17. SQL Server 2005 rétrécit et reconstruit les index
- 18. La clé unique Sql Server est-elle également un index?
- 19. SQL Server 2008: Standard ou SQL Express
- 20. SQL Server De quelle taille est VLDB
- 21. Quelle est la différence entre Shrink et Compact dans SQL Server CE?
- 22. Dans SQL Server 2005, quelle est la différence entre len() et datalength()?
- 23. Quelle est la différence entre SQLNCLI et .NET Framework Fournisseur de données pour SQL Server
- 24. Index de couverture ou index individuels
- 25. SQL Performance Index
- 26. Les index SQL Server ne sont pas utiles
- 27. Tableau et la taille Index dans SQL Server
- 28. Tables SQl Server: pour entasser ou non?
- 29. Quelle différence fait BLOB ou TEXT par rapport à VARCHAR()?
- 30. Mettre en œuvre une différence symétrique dans SQL Server?
Quand vous dites « pas ... » Voulez-vous dire cela ne fonctionnera pas ou la performance sera horrible? –
Je veux dire que l'index ne sera pas utilisé pour la requête. La requête elle-même fonctionnera, bien sûr, mais les performances seront médiocres. – Quassnoi
Dans la première section, le deuxième exemple ne devrait-il pas indiquer "ORDER BY col1 DESC, col2 DESC"? –