कॉलमस्टोर इंडेक्स में पहचान कॉलम


9

मेरे पास एक बहुत बड़ी तालिका IMO (~ 137 मिलियन पंक्तियाँ) है जिसमें बहुत सारे दोहराया डेटा, बहुत सारे NULLकॉलम और ऐसे हैं।

मैं एक तालिका का उपयोग करके इस पर विचार करने पर विचार कर COLUMNSTORE INDEXरहा हूं और मेरे पास IDENTITYमूल तालिका में एक स्तंभ है, जो मेरा एकमात्र स्तंभ है जहां हर पंक्ति अद्वितीय है।

क्या मुझे इस कॉलम को छोड़ देना चाहिए या इसे शामिल करना चाहिए? मैंने पढ़ा है कि आप अपनी तालिका की सभी पंक्तियों को शामिल करना चाहते हैं, COLUMNSTORE INDEXलेकिन मैंने यह भी पढ़ा है कि सर्वश्रेष्ठ उम्मीदवार बहुत सारी गैर-अद्वितीय पंक्तियों वाले कॉलम हैं।

क्या यह सिर्फ एक खराब उम्मीदवार है COLUMNSTORE INDEX?

मैं SQL Server 2012 का उपयोग कर रहा हूं, इसलिए यह एक गैर-सूचीबद्ध कॉलमस्टोर है। मैं अभी इस डेटा को संग्रहीत करने के लिए बेहतर तरीके तलाश रहा हूं। अद्यतन कोई भी नहीं हैं, हालांकि नई पंक्तियों को समय-समय पर ईएलटी प्रक्रिया के माध्यम से जोड़ा जाएगा, इसलिए मुझे लगता है कि कुछ काम वहां किया जाएगा। कुछ लोग इस डेटा को माइन करते हैं और विशाल रिपोर्ट उत्पन्न करते हैं, बहुत सारी पंक्तियों की स्कैनिंग, सर्वर को कई बार क्रॉल में लाती है जिसने हमें एक प्रतिदिन एक सेकेंडरी सर्वर पर कॉपी लोड करने के लिए मजबूर किया है।


1
क्या मूल तालिका पर मौजूद पहचान स्तंभ भी आपका क्लस्टर इंडेक्स है? यदि हां, तो SQL सर्वर स्वचालित रूप से उस कॉलम को किसी भी गैर-क्लस्टर किए गए कॉलमस्टोर इंडेक्स में शामिल करेगा, भले ही आप स्पष्ट रूप से इसके लिए न पूछें। यह कुछ इस तरह से है कि गुच्छित सूचकांक स्तंभों को गैर-क्लस्टर बी-ट्री इंडेक्स में शामिल किया जाएगा, लेकिन डेटा को इस मामले में वास्तविक संपीड़ित कॉलमस्टोर खंडों के रूप में संग्रहीत किया जाएगा। अधिक जानकारी के लिए dba.stackexchange.com/questions/103722/… देखें ।
ज्योफ पैटरसन

137 million rowsबड़ा है, लेकिन प्रबंधनीय है। क्या आपने टेबल को विभाजित करने और विभिन्न फाइलग्रुप पर डालने पर ध्यान दिया है? Sql 2012 में Columnsstore इंडेक्स लेखन योग्य नहीं है, इसलिए आप समस्याओं में भाग लेने जा रहे हैं - आपको इसे छोड़ना और पुन: बनाना होगा। मैं यह नहीं बता रहा हूं कि कॉलमस्टोर खराब है, लेकिन इसके साथ ही अन्य विकल्पों का पता लगाना बेहतर है।
परिजन शाह

जवाबों:


11

पहचान कॉलम वास्तव में SQL Server 2012 में या SQL Server 2014 में Columnstore Index में संपीड़ित नहीं होते हैं। यह वास्तव में आपके द्वारा अनुभव किए जा रहे कार्यभार पर निर्भर करेगा। यदि आपके कार्यभार में पहचान कॉलम शामिल है, तो आप बहुत ही खूबसूरती से सेगमेंट एलिमिनेशन का लाभ उठा सकते हैं

संपीड़न के दृष्टिकोण से - कॉलमस्टोर आपको आमतौर पर पेज की तुलना में बेहतर संपीड़न प्रदान करेगा। आमतौर पर। उत्पादन को आगे बढ़ाने से पहले कृपया इसका परीक्षण करें।

SQL Server 2012 में आपकी सबसे बड़ी समस्या बैच मोड का बहुत कमजोर कार्यान्वयन होगा, और ऐसा कुछ भी नहीं है जो आप इसके बारे में कर सकते हैं।


7
स्वागत है निको !!!
हारून बर्ट्रेंड

3

मैं एक और जवाब (स्वागत, निको!) के साथ निको में शामिल होने का विरोध नहीं कर सका। सामान्य तौर पर, मैं निको से सहमत हूं कि एसक्यूएल 2012 में बैच मोड की सीमाएं (यदि निको अपने स्वयं के ब्लॉग से लिंक नहीं करेगा, तो मैं :)) एक प्रमुख चिंता का विषय हो सकता है। लेकिन अगर आप उन लोगों के साथ रह सकते हैं और आपके पास हर उस क्वेरी पर पूरा नियंत्रण है, जिसे आप टेबल के खिलाफ लिख रहे हैं, तो ध्यान से वीटीएस करें, तो कॉलमस्टोर SQL 2012 में आपके लिए काम कर सकता है।

जहाँ तक पहचान कॉलम के बारे में आपके विशिष्ट प्रश्न हैं, मैंने पाया कि पहचान कॉलम बहुत अच्छी तरह से संपीड़ित करता है और आपके किसी भी प्रारंभिक परीक्षण में आपके कॉलमस्टोर इंडेक्स में इसे शामिल करने की अत्यधिक अनुशंसा करेगा। (ध्यान दें कि यदि पहचान कॉलम आपके बी-ट्री का क्लस्टर इंडेक्स भी होता है, तो यह स्वचालित रूप से आपके गैर-क्लस्टर किए गए कॉलमस्टोर इंडेक्स में शामिल हो जाएगा ।)

संदर्भ के लिए, यहां वे आकार हैं जिन्हें मैंने पहचान कॉलम डेटा की ~ 10 मिमी पंक्तियों के लिए मनाया है। इष्टतम सेगमेंट के उन्मूलन के लिए लोड किया गया कॉलमस्टोर 26MB (बनाम पंक्ति की PAGEतालिका के संपीड़न के लिए 113MB) तक संकुचित होता है, और यहां तक ​​कि बेतरतीब ढंग से ऑर्डर किए गए बी-ट्री पर बनाया गया कॉलमस्टोर केवल 40 एमबी है। तो यह एक बड़ा संपीड़न लाभ दिखाता है, यहां तक ​​कि सबसे अच्छा बी-ट्री संपीड़न एसक्यूएल की पेशकश करने के लिए और यहां तक ​​कि अगर आप इष्टतम खंड उन्मूलन के लिए अपने डेटा को संरेखित करने के लिए परेशान नहीं करते हैं (जो आप पहले बी-ट्री बनाकर करेंगे और फिर MAXDOP1 के साथ अपने स्तंभ का निर्माण )।

यहां छवि विवरण दर्ज करें

यहां वह पूरी स्क्रिप्ट है जिसका उपयोग मैंने उस स्थिति में किया है, जिसे आप खेलना चाहते हैं:

-- 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

सभी महान उत्तरों के लिए धन्यवाद, अभी मैंने कम से कम sql server 2014 को प्राप्त करने का निर्णय लिया है। हम अपने अपग्रेड को आगे बढ़ा रहे हैं इसलिए मैं अगले वर्ष में उम्मीद कर रहा हूं या हम ऐसा कर सकते हैं।
डॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.