Sütun deposu dizinindeki kimlik sütunu


9

Çok sayıda tekrarlanan veri, çok sayıda NULLsütun ve benzeri çok büyük bir tablo IMO (~ 137 milyon satır) var .

Bir ile bir tablo kullanarak bu keşfetmek düşünüyorum COLUMNSTORE INDEXve her IDENTITYtabloda benzersiz olan benim tek sütun olan özgün tabloda bir sütun var .

Bu sütunu dışarıda bırakmalı mıyım yoksa eklemeli miyim? Tablonuzun tüm satırlarını içine dahil etmek istediğinizi okudum, COLUMNSTORE INDEXancak en iyi adayların çok sayıda benzersiz olmayan satır içeren sütunlar olduğunu da okudum.

Bu sadece kötü bir aday COLUMNSTORE INDEXmı?

SQL Server 2012 kullanıyorum, bu yüzden kümelenmemiş bir sütun deposudur. Sadece bu verileri depolamanın daha iyi yollarını araştırıyorum. Yeni satırlar bir ELT işlemi aracılığıyla periyodik olarak eklenecek olsa da, güncellemeler mevcut değil, bu yüzden orada bazı işlerin yapılacağını varsayıyorum. Bazı kişiler bu verileri benimser ve büyük raporlar oluşturur, çok sayıda satır tarar, sunucuyu bazen günlük olarak bir kopyasını ikincil bir sunucuya yüklememize zorlayan bir tarama yapar.


1
Özgün tablodaki kimlik sütunu da kümelenmiş dizininiz mi? Öyleyse, SQL Server, açıkça istemeseniz bile, bu sütunu kümelenmemiş herhangi bir sütun deposu dizinine otomatik olarak ekler. Bu, kümelenmiş dizin sütunlarının kümelenmemiş bir b ağacı dizinine dahil edilmesine benzer, ancak veriler bu durumda gerçek sıkıştırılmış sütun deposu segmentleri olarak saklanır. Daha fazla bilgi için dba.stackexchange.com/questions/103722/… adresine bakın .
Geoff Patterson

137 million rowsbüyük ama yönetilebilir. Tabloyu bölümlere ayırmayı ve farklı dosya gruplarına koymayı düşündünüz mü? Sql 2012'deki Columnsstore dizini yazılabilir değildir, bu yüzden sorunlara gireceksiniz - bırakıp yeniden oluşturmanız gerekir. Columntore iradesinin kötü olduğunu söylemiyorum, ama diğer seçenekleri de keşfetmek daha iyi.
Kin Shah

Yanıtlar:


11

Kimlik sütunları, SQL Server 2012 veya SQL Server 2014'teki Columnstore Dizinlerinde tam olarak sıkıştırılmaz. Tüm bunlar, yaşadığınız iş yüküne bağlıdır. İş yükünüz kimlik sütununu içerecekse, Segment eliminasyonundan çok güzel bir şekilde yararlanabilirsiniz .

Sıkıştırma bakış açısından - Columnstore, size normalde olduğundan daha iyi sıkıştırma sağlar. Tipik. Üretime geçmeden önce lütfen test edin.

SQL Server 2012'deki en büyük sorununuz Toplu Mod'un çok zayıf bir uygulaması olacaktır ve bu konuda yapabileceğiniz hiçbir şey yoktur.


7
Hoşgeldiniz Niko !!!
Aaron Bertrand

3

Niko'ya başka bir cevapla katılmaya direnemedim (hoş geldiniz, Niko!). Genel olarak, Niko ile SQL 2012'deki toplu mod sınırlamalarının (Niko kendi bloguna bağlanmayacaksa, yapacağım :) büyük bir endişe olabileceğini kabul ediyorum. Ancak bunlarla yaşayabilir ve dikkatle incelemek için tabloya yazdığınız her sorgu üzerinde tam kontrole sahipseniz, columntore SQL 2012'de sizin için çalışabilir.

Kimlik sütunu ile ilgili özel sorularınıza gelince, kimlik sütununun çok iyi sıkıştırdığını ve sizi ilk testlerde sütun deposu dizininize eklemenizi şiddetle tavsiye ediyorum. (Kimlik sütunu, b ağacınızın kümelenmiş dizini de olursa, otomatik olarak kümelenmemiş sütun deposu dizininize ekleneceğini unutmayın .)

Referans için, burada kimlik sütunu verilerinin ~ 10MM satırları için gözlemlediğim boyutlar. Optimal segment eliminasyonu için yüklenen sütun deposu 26MB'a PAGEsıkıştırır (sıra mağaza tablosunun sıkıştırılması için 113MB'ye karşılık gelir) ve rastgele sıralı bir b-ağacı üzerine inşa edilen sütun deposu bile sadece 40MB'dir. Bu, SQL'in sunduğu en iyi b-ağacı sıkıştırması üzerinde bile ve verilerinizi en uygun segment eliminasyonu için hizalamak için uğraşmasanız bile (önce bir b-ağacı oluşturarak ve sonra yapacağınız) büyük bir sıkıştırma avantajı gösterir. sütun mağazanızı oluşturma MAXDOP1).

resim açıklamasını buraya girin

İşte oynamak istediğinizde kullandığım tam komut dosyası:

-- Confirm SQL version
SELECT @@version
--Microsoft SQL Server 2012 - 11.0.5613.0 (X64) 
--  May  4 2015 19:05:02 
--  Copyright (c) Microsoft Corporation
--  Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: )


-- Create a columnstore table with identity column that is the primary key
-- This will yield 10 columnstore segments @ 1048576 rows each
SELECT i = IDENTITY(int, 1, 1), ROW_NUMBER() OVER (ORDER BY randGuid) as randCol
INTO #testIdentityCompression_sortedColumnstore
FROM (
    SELECT TOP 10485760 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS randI, NEWID() AS randGuid
    FROM master..spt_values v1
    CROSS JOIN master..spt_values v2
    CROSS JOIN master..spt_values v3
) r
ORDER BY r.randI
GO
ALTER TABLE #testIdentityCompression_sortedColumnstore
ADD PRIMARY KEY (i)
GO
-- Load using a pre-ordered b-tree and one thread for optimal segment elimination
-- See http://www.nikoport.com/2014/04/16/clustered-columnstore-indexes-part-29-data-loading-for-better-segment-elimination/
CREATE NONCLUSTERED COLUMNSTORE INDEX cs_#testIdentityCompression_sortedColumnstore ON #testIdentityCompression_sortedColumnstore (i) WITH (MAXDOP = 1)
GO

-- Create another table with the same data, but randomly ordered
SELECT *
INTO #testIdentityCompression_randomOrderColumnstore
FROM #testIdentityCompression_sortedColumnstore
GO
ALTER TABLE #testIdentityCompression_randomOrderColumnstore
ADD UNIQUE CLUSTERED (randCol)
GO
CREATE NONCLUSTERED COLUMNSTORE INDEX cs_#testIdentityCompression_randomOrderColumnstore ON #testIdentityCompression_randomOrderColumnstore (i) WITH (MAXDOP = 1)
GO

-- Create a b-tree with the identity column data and no compression
-- Note that we copy over only the identity column since we'll be looking at the total size of the b-tree index
-- If anything, this gives an unfair "advantage" to the rowstore-page-compressed version since more
-- rows fit on a page and page compression rates should be better without the "randCol" column.
SELECT i
INTO #testIdentityCompression_uncompressedRowstore
FROM #testIdentityCompression_sortedColumnstore
GO
ALTER TABLE #testIdentityCompression_uncompressedRowstore
ADD PRIMARY KEY (i)
GO

-- Create a b-tree with the identity column and page compression
SELECT i
INTO #testIdentityCompression_compressedRowstore
FROM #testIdentityCompression_sortedColumnstore
GO
ALTER TABLE #testIdentityCompression_compressedRowstore
ADD PRIMARY KEY (i)
WITH (DATA_COMPRESSION = PAGE)
GO

-- Compare all the sizes!
SELECT OBJECT_NAME(p.object_id, 2) AS tableName, COUNT(*) AS num_segments, SUM(on_disk_size / (1024.*1024.)) as size_mb
FROM tempdb.sys.partitions p
JOIN tempdb.sys.column_store_segments s
    ON s.partition_id = p.partition_id
    AND s.column_id = 1
WHERE p.object_id IN (OBJECT_ID('tempdb..#testIdentityCompression_sortedColumnstore'),OBJECT_ID('tempdb..#testIdentityCompression_randomOrderColumnstore'))
GROUP BY p.object_id
UNION ALL
SELECT OBJECT_NAME(p.object_id, 2) AS tableName
    , NULL AS num_segments
    , (a.total_pages*8.0) / (1024.0) as size_mb
FROM tempdb.sys.partitions p
JOIN tempdb.sys.allocation_units a
    ON a.container_id = p.partition_id
WHERE p.object_id IN (OBJECT_ID('tempdb..#testIdentityCompression_compressedRowstore'),OBJECT_ID('tempdb..#testIdentityCompression_uncompressedRowstore'))
ORDER BY 3 ASC
GO

Tüm harika cevaplar için teşekkür ederim, şu anda en az sql server 2014'e kadar dayanamaya karar verdim.
Don
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.