J'ai une table simple avec un indice de colonne en cluster:
ID INT NOT NULL,
Hash BINARY(20) NOT NULL
Cette table compte quelque milliards de lignes et selon l'sp_spaceused
, sys.allocation_units
et SSMS rapporte que sa taille est d'environ 25 Go.
Mon problème est que je ne peux pas rendre compte de tout cet espace. Interrogation sys.column_store_row_groups
et sys.column_store_segments
ne me donne qu'environ 7,8 Go. L'index n'utilise aucun dictionnaire: primary_dictionary_id
et secondary_dictionary_id
sont -1 pour tous les segments. Interrogation sys.column_store_dictionaries
ne renvoie pas de lignes du tout.
Le tuple déménageur a fait son travail et tous les groupes de lignes sont dans l'état comprimé. J'ai déjà essayé un ALTER INDEX REORGANIZE
Au cas où.
Ma seule idée de la différence de taille est des éléments de type dictionnaire Je ne comptabilise pas. Des idées sur ce que je pourrais manquer?
Je cours SQL Server 2017 (RTM-CU4).
Edit 1 :
Ceci est la sortie de sp_spacaced pour la table en question:
+--------+------------+-------------+-------------+------------+----------+
| name | rows | reserved | data | index_size | unused |
+--------+------------+-------------+-------------+------------+----------+
| IdsBin | 1073741824 | 25028112 KB | 25007432 KB | 16 KB | 20664 KB |
+--------+------------+-------------+-------------+------------+----------+
Edit 2 :
Ceci est un script de reproduction avec 1 million de lignes. Il court environ 1 minute sur ma machine. AVERTISSEMENT : Il choutes et recrée une nouvelle base de données
USE master;
GO
DROP DATABASE IF EXISTS MyDbWeirdTest;
GO
CREATE DATABASE MyDbWeirdTest;
GO
USE MyDbWeirdTest;
GO
CREATE TABLE IdsBin (
ID INT NOT NULL,
Hash BINARY(20) NOT NULL
);
CREATE CLUSTERED COLUMNSTORE INDEX ix1 ON IdsBin
GO
CREATE TYPE tBin AS TABLE (
ID INT,
Hash BINARY(20)
);
GO
CREATE OR ALTER PROCEDURE pBin (
@ids AS dbo.tBin READONLY
)
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.IdsBin
SELECT ID, Hash FROM @ids;
END;
GO
SET NOCOUNT ON;
DECLARE @i INT = 1, @t INT = 1;
DECLARE @tvp dbo.tBin;
WHILE @t <= 1000000
BEGIN
DELETE @tvp;
BEGIN TRAN;
WHILE @i <= 1000
BEGIN
INSERT @tvp VALUES (@t, HASHBYTES('SHA1', CAST(@t AS BINARY(4))));
SET @i = @i + 1;
SET @t = @t + 1;
END;
EXEC pBin @tvp;
COMMIT;
SET @i = 1;
END;
GO
ALTER INDEX ix1 on IdsBin REBUILD;
GO
Pour ce reprovement, SP_SPACEUDED montre:
+--------+----------------------+----------+----------+------------+--------+
| name | rows | reserved | data | index_size | unused |
+--------+----------------------+----------+----------+------------+--------+
| IdsBin | 1000000 | 22728 KB | 22640 KB | 0 KB | 88 KB |
+--------+----------------------+----------+----------+------------+--------+
sys.Column_Store_row_groups:
+-----------+----------+------------------+--------------+---------------------+-------+-------------------+------------+--------------+---------------+
| object_id | index_id | partition_number | row_group_id | delta_store_hobt_id | state | state_description | total_rows | deleted_rows | size_in_bytes |
+-----------+----------+------------------+--------------+---------------------+-------+-------------------+------------+--------------+---------------+
| 901578250 | 1 | 1 | 0 | NULL | 3 | COMPRESSED | 1000000 | 0 | 5896938 |
+-----------+----------+------------------+--------------+---------------------+-------+-------------------+------------+--------------+---------------+
SO SP_SPACEUSUtilisé me donne environ 22 Mo et SYS.Allocation_units (non indiqués) accepte. Mais aucun ColuminStore DMVS semble être d'accord sur ce numéro et disent que l'indice est inférieur à 6 Mo de taille.
sys.column_store_segments
et sys.column_store_row_groups
Store Quelques des informations de métadonnées sur les données de colonne, mais je crois que cela finit par représenter le compressé Taille. Il existe également des structures lobes qui sont également allouées et vous pouvez voir la taille non compressée dans l'unité d'allocation/la partition DMVS (et si vous arrivez aux pages d'une manière ou d'une autre avec DBCC PAGE
, Je parie que vous verriez qu'ils sont relativement vides). En d'autres termes, sys.column_store_row_groups
vous montre combien de données stockées sur ces pages, mais n'en ajoute pas dans l'espace libre sur ces pages (qui prennent toujours de la place dans le fichier de données et en mémoire, comme un index fragmenté ou un index avec un index fragmenté. facteur de remplissage).
J'ai couru votre repro et voici ce que j'ai vu:
SELECT
a.[type_desc],
p.[rows],
a.total_pages, reserved_kb = a.total_pages * 8,
a.used_pages, data_kb = a.used_pages * 8
FROM sys.allocation_units AS a
INNER JOIN sys.partitions AS p
ON a.container_id = p.[partition_id]
WHERE p.[object_id] = OBJECT_ID(N'dbo.IdsBin');
Résultats:
Autre que inutilisé, que je n'ai pas pris la peine de calculer, les résultats correspondent à sp_spaceused
:
Et vous pouvez confirmer ces chiffres dans sys.dm_db_partition_stats
ainsi que:
SELECT
lob_reserved_page_count, reserved_kb = lob_reserved_page_count * 8,
lob_used_page_count, data_kb = lob_used_page_count * 8
FROM sys.dm_db_partition_stats
WHERE [object_id] = OBJECT_ID(N'dbo.IdsBin');
Résultats:
Vous avez mentionné cela mais je voulais juste appeler explicitement que sp_spaceused
et allocation_units
reflète le nombre de pages, peu importe la manière dont une page complète ou vide pourrait être. Les groupes de lignes DMV reflètent uniquement les données réelles. la documentation stipule (emphasis mine):
Taille en octets de tous Les données dans ce groupe de lignes (non compris les métadonnées ou les dictionnaires partagés)
Alors que sys.dm_db_partition_stats
, par exemple, indique explicitement les pages tout au long, pas des données, même si je dirais qu'ils devraient spécifier que chaque LOB est une page de 8K ici:
Nombre total de lobes utilisés pour stocker et gérer l'indice de colonne dans la partition.
Quel numéro vous voulez faire confiance, eh bien, c'est à vous de décider.
En écart, Niko Neugebauer a parlé du fait que seule la taille comprimée des dictionnaires est exposée dans la colonne DMVS ici , et relevée A élément de rétroaction À ce sujet. Il me semble que d'autres informations pourraient également être exposées dans la colonne DMVS.