मैं एक सूचकांक की लागत पर अपने कार्यालय में विभिन्न डेवलपर्स के साथ चल रही बहस कर रहा हूं, और क्या अद्वितीयता फायदेमंद है या नहीं (शायद दोनों)। इस मुद्दे की जड़ हमारे प्रतिस्पर्धी संसाधन हैं।
पृष्ठभूमि
मैंने पहले एक चर्चा पढ़ी है जिसमें कहा गया है कि एक Unique
अनुक्रमणिका को बनाए रखने के लिए कोई अतिरिक्त लागत नहीं है, क्योंकि एक Insert
ऑपरेशन जहां यह बी-ट्री में फिट बैठता है, और अगर कोई डुप्लिकेट गैर-अनूठे इंडेक्स में पाया जाता है, के लिए जाँच करता है, तो एक यूनिकफायर को भेजता है। कुंजी का अंत, लेकिन अन्यथा सीधे सम्मिलित करता है। घटनाओं के इस क्रम में, एक Unique
सूचकांक की कोई अतिरिक्त लागत नहीं है।
मेरे सहकर्मी ने यह कहकर इस कथन का मुकाबला किया Unique
के बाद बी-वृक्ष में नए स्थान की तलाश है, और इस प्रकार अधिक एक गैर-अद्वितीय सूचकांक की तुलना में बनाए रखने के लिए महंगा है एक दूसरे ऑपरेशन के रूप में लागू की जाती है।
सबसे खराब रूप से, मैंने एक पहचान स्तंभ (अंतर्निहित अद्वितीय) के साथ तालिकाओं को देखा है जो तालिका की क्लस्टरिंग कुंजी है, लेकिन स्पष्ट रूप से गैर-अद्वितीय के रूप में कहा गया है। सबसे बुरे पक्ष में विशिष्टता के साथ मेरा जुनून है, और सभी सूचकांक अद्वितीय के रूप में बनाए जाते हैं, और जब किसी सूचकांक के लिए स्पष्ट रूप से अद्वितीय संबंध को परिभाषित करना संभव नहीं होता है, तो मैं तालिका के पीके को सूचकांक के अंत तक सुनिश्चित करने के लिए अपील करता हूं। विशिष्टता की गारंटी है।
मैं अक्सर देव टीम के लिए कोड समीक्षाओं में शामिल होता हूं, और मुझे उनके पालन के लिए सामान्य दिशानिर्देश देने में सक्षम होना चाहिए। हां, प्रत्येक सूचकांक का मूल्यांकन किया जाना चाहिए, लेकिन जब आपके पास प्रत्येक में हजारों तालिकाओं के साथ पांच सर्वर होते हैं और एक मेज पर बीस सूचकांक होते हैं, तो आपको गुणवत्ता के एक निश्चित स्तर को सुनिश्चित करने के लिए कुछ सरल नियमों को लागू करने में सक्षम होना चाहिए।
सवाल
क्या Insert
गैर-अद्वितीय सूचकांक को बनाए रखने की लागत की तुलना में विशिष्टता के पीछे-छोर पर एक अतिरिक्त लागत है ? दूसरे, अद्वितीयता सुनिश्चित करने के लिए एक सूचकांक के अंत में एक तालिका के प्राथमिक कुंजी को जोड़ने में क्या गलत है?
उदाहरण तालिका परिभाषा
create table #test_index
(
id int not null identity(1, 1),
dt datetime not null default(current_timestamp),
val varchar(100) not null,
is_deleted bit not null default(0),
primary key nonclustered(id desc),
unique clustered(dt desc, id desc)
);
create index
[nonunique_nonclustered_example]
on #test_index
(is_deleted)
include
(val);
create unique index
[unique_nonclustered_example]
on #test_index
(is_deleted, dt desc, id desc)
include
(val);
उदाहरण
एक Unique
सूचकांक के अंत की कुंजी मैं क्यों जोड़ूंगा इसका एक उदाहरण हमारे एक तथ्य तालिका में है। वहाँ एक है Primary Key
एक है कि Identity
स्तंभ। हालाँकि, Clustered Index
इसके बजाए विभाजन स्कीम कॉलम है, जिसके बाद तीन विदेशी कुंजी आयाम हैं जिनमें कोई विशिष्टता नहीं है। इस तालिका पर प्रदर्शन का चयन संक्षिप्त है, और मैं अक्सर Primary Key
लीवरेज करने के बजाय एक महत्वपूर्ण लुकअप के साथ बेहतर समय का उपयोग करता हूं Clustered Index
। अन्य तालिकाएँ जो एक समान डिज़ाइन का पालन करती हैं, लेकिन Primary Key
अंत तक संलग्न होती हैं, उनमें बेहतर प्रदर्शन होता है।
-- date_int is equivalent to convert(int, convert(varchar, current_timestamp, 112))
if not exists(select * from sys.partition_functions where [name] = N'pf_date_int')
create partition function
pf_date_int (int)
as range right for values
(19000101, 20180101, 20180401, 20180701, 20181001, 20190101, 20190401, 20190701);
go
if not exists(select * from sys.partition_schemes where [name] = N'ps_date_int')
create partition scheme
ps_date_int
as partition
pf_date_int all
to
([PRIMARY]);
go
if not exists(select * from sys.objects where [object_id] = OBJECT_ID(N'dbo.bad_fact_table'))
create table dbo.bad_fact_table
(
id int not null, -- Identity implemented elsewhere, and CDC populates
date_int int not null,
dt date not null,
group_id int not null,
group_entity_id int not null, -- member of group
fk_id int not null,
-- tons of other columns
primary key nonclustered(id, date_int),
index [ci_bad_fact_table] clustered (date_int, group_id, group_entity_id, fk_id)
)
on ps_date_int(date_int);
go
if not exists(select * from sys.objects where [object_id] = OBJECT_ID(N'dbo.better_fact_table'))
create table dbo.better_fact_table
(
id int not null, -- Identity implemented elsewhere, and CDC populates
date_int int not null,
dt date not null,
group_id int not null,
group_entity_id int not null, -- member of group
-- tons of other columns
primary key nonclustered(id, date_int),
index [ci_better_fact_table] clustered(date_int, group_id, group_entity_id, id)
)
on ps_date_int(date_int);
go
Case
औरIf
संरचनाएं 10 स्तरों तक सीमित हैं, यह समझ में आता है कि गैर-अद्वितीय संस्थाओं को हल करने की एक सीमा भी है। आपके कथन से, ऐसा लगता है कि यह केवल उन मामलों पर लागू होता है जब क्लस्टरिंग कुंजी गैर-अद्वितीय होती है। क्या यह एक समस्या हैNonclustered Index
या यदि क्लस्टरिंग कुंजी हैUnique
तोNonclustered
अनुक्रमणिका के लिए कोई समस्या नहीं है ?