ดัชนีค่าใช้จ่ายที่ไม่ซ้ำกัน


14

ฉันได้มีการถกเถียงอย่างต่อเนื่องกับนักพัฒนาหลายคนในสำนักงานของฉันเกี่ยวกับค่าใช้จ่ายของดัชนีและความเป็นเอกลักษณ์หรือไม่นั้นมีประโยชน์หรือมีค่าใช้จ่ายสูง (อาจเป็นได้ทั้งสองอย่าง) ปมของปัญหาคือทรัพยากรการแข่งขันของเรา

พื้นหลัง

ก่อนหน้านี้ฉันได้อ่านการสนทนาที่ระบุว่าUniqueดัชนีนั้นไม่มีค่าใช้จ่ายเพิ่มเติมในการบำรุงรักษาเนื่องจากการInsertดำเนินการโดยปริยายจะตรวจสอบว่าตรงกับต้นไม้ B หรือไม่และหากพบซ้ำในดัชนีที่ไม่ซ้ำใคร จุดสิ้นสุดของคีย์ แต่อย่างอื่นแทรกโดยตรง ในลำดับเหตุการณ์นี้Uniqueดัชนีไม่มีค่าใช้จ่ายเพิ่มเติม

ผู้ร่วมงานของฉันต่อสู้กับแถลงการณ์นี้โดยกล่าวว่าการUniqueบังคับใช้เป็นการดำเนินการครั้งที่สองหลังจากการค้นหาตำแหน่งใหม่ในต้นไม้ B และทำให้ค่าใช้จ่ายในการบำรุงรักษาสูงกว่าดัชนีที่ไม่ซ้ำใคร

ที่แย่ที่สุดฉันได้เห็นตารางที่มีคอลัมน์ข้อมูลประจำตัว (ไม่ซ้ำกันโดยเนื้อแท้) นั่นคือคีย์การทำคลัสเตอร์ของตาราง แต่ระบุไว้อย่างชัดเจนว่าไม่ซ้ำกัน ในอีกด้านหนึ่งของความเลวร้ายที่สุดคือการครอบงำจิตใจของฉันด้วยเอกลักษณ์และดัชนีทั้งหมดจะถูกสร้างขึ้นเป็นเอกลักษณ์และเมื่อไม่สามารถกำหนดความสัมพันธ์ที่ไม่ซ้ำกันอย่างชัดเจนกับดัชนีฉันผนวก PK ของตารางไปยังจุดสิ้นสุดของดัชนีเพื่อรับรอง รับประกันความเป็นเอกลักษณ์

ฉันมีส่วนร่วมในการตรวจสอบโค้ดสำหรับทีม dev บ่อยครั้งและฉันต้องสามารถให้แนวทางทั่วไปเพื่อให้พวกเขาทำตาม ใช่ทุกดัชนีควรได้รับการประเมิน แต่เมื่อคุณมีเซิร์ฟเวอร์ห้าตัวที่มีตารางนับพันแต่ละตัวและมากถึงยี่สิบดัชนีในตารางคุณจะต้องสามารถใช้กฎง่าย ๆ เพื่อรับประกันคุณภาพในระดับหนึ่ง

คำถาม

เอกลักษณ์มีค่าใช้จ่ายเพิ่มเติมที่ส่วนท้ายของการ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

คำตอบ:


16

ฉันมีส่วนร่วมในการตรวจสอบโค้ดสำหรับทีม dev บ่อยครั้งและฉันต้องสามารถให้แนวทางทั่วไปเพื่อให้พวกเขาทำตาม

สภาพแวดล้อมที่ฉันเกี่ยวข้องในปัจจุบันมีเซิร์ฟเวอร์ 250 เครื่องพร้อมฐานข้อมูล 2500 ตัว ผมเคยทำงานในระบบที่มี30,000 ฐานข้อมูล แนวทางการจัดทำดัชนีควรหมุนรอบการประชุมตั้งชื่อ ฯลฯ ไม่เป็น "กฎ" สำหรับสิ่งที่คอลัมน์ที่จะรวมไว้ในดัชนี - ทุกดัชนีของแต่ละบุคคลควรได้รับการออกแบบมาเพื่อเป็นดัชนีที่ถูกต้องในการปกครองธุรกิจเฉพาะหรือรหัสสัมผัสตาราง

เอกลักษณ์มีค่าใช้จ่ายเพิ่มเติมที่ส่วนท้ายของการInsertเปรียบเทียบกับค่าใช้จ่ายในการบำรุงรักษาดัชนีที่ไม่ซ้ำหรือไม่? ประการที่สองมีอะไรผิดปกติในการผนวกคีย์หลักของตารางต่อท้ายดัชนีเพื่อให้แน่ใจว่ามีเอกลักษณ์?

การเพิ่มคอลัมน์คีย์หลักในตอนท้ายของดัชนีที่ไม่ซ้ำกันเพื่อทำให้มันดูเป็นเอกลักษณ์สำหรับฉันเป็นรูปแบบการต่อต้าน หากกฎธุรกิจกำหนดข้อมูลควรไม่ซ้ำกันให้เพิ่มข้อ จำกัด ที่ไม่ซ้ำกันในคอลัมน์ ซึ่งจะสร้างดัชนีที่ไม่ซ้ำกันโดยอัตโนมัติ หากคุณกำลังจัดทำดัชนีคอลัมน์สำหรับประสิทธิภาพเหตุใดคุณจึงต้องเพิ่มคอลัมน์ในดัชนี

แม้ว่าการคาดคะเนของคุณที่บังคับให้มีลักษณะเฉพาะนั้นไม่ได้เพิ่มค่าใช้จ่ายเพิ่มเติมใด ๆ ที่ถูกต้อง (ซึ่งไม่ใช่ในบางกรณี) คุณกำลังแก้ไขอะไรโดยใช้ดัชนีที่ซับซ้อนโดยไม่จำเป็น

ในอินสแตนซ์เฉพาะของการเพิ่มคีย์หลักไปยังจุดสิ้นสุดของคีย์ดัชนีของคุณเพื่อให้คุณสามารถกำหนดคำนิยามดัชนีรวมถึงการUNIQUEปรับมันจริง ๆ แล้วมันสร้างความแตกต่างเป็นศูนย์กับโครงสร้างดัชนีทางกายภาพบนดิสก์ นี่เป็นเพราะลักษณะของโครงสร้างของปุ่มดัชนี B-tree ซึ่งสิ่งเหล่านี้จำเป็นต้องเป็นเอกลักษณ์เสมอ

ดังที่เดวิดบราวน์พูดถึงในความคิดเห็น:

เนื่องจากดัชนีที่ไม่ได้จัดกลุ่มทั้งหมดจะถูกจัดเก็บเป็นดัชนีที่ไม่ซ้ำใครจึงไม่มีค่าใช้จ่ายเพิ่มเติมในการแทรกเข้าไปในดัชนีที่ไม่ซ้ำใคร ในความเป็นจริงมีค่าใช้จ่ายเพิ่มเติมเพียงอย่างเดียวที่จะไม่สามารถประกาศคีย์ตัวเลือกเป็นดัชนีที่ไม่ซ้ำซึ่งจะทำให้คีย์ดัชนีแบบคลัสเตอร์ถูกผนวกเข้ากับคีย์ดัชนี

ทำตัวอย่างต่อไปนี้ให้สมบูรณ์และตรวจสอบได้น้อยที่สุด :

USE tempdb;

DROP TABLE IF EXISTS dbo.IndexTest;
CREATE TABLE dbo.IndexTest
(
    id int NOT NULL
        CONSTRAINT IndexTest_pk
        PRIMARY KEY
        CLUSTERED
        IDENTITY(1,1)
    , rowDate datetime NOT NULL
);

ฉันจะเพิ่มดัชนีสองตัวที่เหมือนกันยกเว้นการเพิ่มคีย์หลักที่ส่วนท้ายของนิยามคีย์ดัชนีที่สอง:

CREATE INDEX IndexTest_rowDate_ix01
ON dbo.IndexTest(rowDate);

CREATE UNIQUE INDEX IndexTest_rowDate_ix02
ON dbo.IndexTest(rowDate, id);

ต่อไปเราจะทำหลายแถวในตาราง:

INSERT INTO dbo.IndexTest (rowDate)
VALUES (DATEADD(SECOND, 0, GETDATE()))
     , (DATEADD(SECOND, 0, GETDATE()))
     , (DATEADD(SECOND, 0, GETDATE()))
     , (DATEADD(SECOND, 1, GETDATE()))
     , (DATEADD(SECOND, 2, GETDATE()));

ดังที่คุณเห็นด้านบนสามแถวมีค่าเดียวกันสำหรับrowDateคอลัมน์และสองแถวมีค่าที่ไม่ซ้ำกัน

ต่อไปเราจะดูโครงสร้างหน้าทางกายภาพสำหรับแต่ละดัชนีโดยใช้DBCC PAGEคำสั่งที่ไม่มีเอกสาร:

DECLARE @dbid int = DB_ID();
DECLARE @fileid int;
DECLARE @pageid int;
DECLARE @indexid int;

SELECT @fileid = ddpa.allocated_page_file_id
    , @pageid = ddpa.allocated_page_page_id
FROM sys.indexes i 
CROSS APPLY sys.dm_db_database_page_allocations(DB_ID(), i.object_id, i.index_id, NULL, 'LIMITED') ddpa
WHERE i.name = N'IndexTest_rowDate_ix01'
    AND ddpa.is_allocated = 1
    AND ddpa.is_iam_page = 0;

PRINT N'*************************************** IndexTest_rowDate_ix01 *****************************************';
DBCC TRACEON(3604);
DBCC PAGE (@dbid, @fileid, @pageid, 1);
DBCC TRACEON(3604);
PRINT N'*************************************** IndexTest_rowDate_ix01 *****************************************';

SELECT @fileid = ddpa.allocated_page_file_id
    , @pageid = ddpa.allocated_page_page_id
FROM sys.indexes i 
CROSS APPLY sys.dm_db_database_page_allocations(DB_ID(), i.object_id, i.index_id, NULL, 'LIMITED') ddpa
WHERE i.name = N'IndexTest_rowDate_ix02'
    AND ddpa.is_allocated = 1
    AND ddpa.is_iam_page = 0;

PRINT N'*************************************** IndexTest_rowDate_ix02 *****************************************';
DBCC TRACEON(3604);
DBCC PAGE (@dbid, @fileid, @pageid, 1);
DBCC TRACEON(3604);
PRINT N'*************************************** IndexTest_rowDate_ix02 *****************************************';

ฉันได้ดูผลลัพธ์โดยใช้ Beyond Compare และยกเว้นความแตกต่างที่ชัดเจนเกี่ยวกับ ID หน้าการจัดสรร ฯลฯ โครงสร้างดัชนีสองรายการจะเหมือนกัน

ป้อนคำอธิบายรูปภาพที่นี่

คุณอาจใช้วิธีข้างต้นเพื่อหมายความว่ารวมถึงคีย์หลักในทุกดัชนีและการกำหนดที่ไม่เหมือนใครคือ A Good Thing ™เนื่องจากนั่นเป็นสิ่งที่เกิดขึ้นภายใต้การครอบคลุม ฉันจะไม่ทำให้สมมติฐานนั้นและจะแนะนำเฉพาะการกำหนดดัชนีที่ไม่ซ้ำกันถ้าในความเป็นจริงข้อมูลธรรมชาติในดัชนีที่ไม่ซ้ำกันอยู่แล้ว

มีทรัพยากรที่ยอดเยี่ยมหลายประการใน Interwebz เกี่ยวกับหัวข้อนี้รวมถึง:

FYI การมีอยู่ของidentityคอลัมน์ไม่รับประกันความเป็นเอกลักษณ์ คุณจำเป็นต้องกำหนดคอลัมน์เป็นคีย์หลักหรือมีข้อ จำกัด ที่ไม่ซ้ำกันเพื่อให้แน่ใจว่าค่าที่เก็บไว้ในคอลัมน์นั้นเป็นจริงที่ไม่ซ้ำกัน คำสั่งจะช่วยให้คุณสามารถแทรกไปเป็นค่าที่ไม่ซ้ำกันในคอลัมน์กำหนดให้เป็นSET IDENTITY_INSERT schema.table ON;identity


5

เพียงแค่ add-on คำตอบที่ดีแม็กซ์

เมื่อมันมาถึงการสร้างดัชนีคลัสเตอร์ที่ไม่ซ้ำกัน SQL Server สร้างสิ่งที่เรียกว่าUniquifierในพื้นหลังอย่างไรก็ตาม

สิ่งนี้Uniquifierอาจทำให้เกิดปัญหาที่อาจเกิดขึ้นในอนาคตหากแพลตฟอร์มของคุณมีการดำเนินงาน CRUD จำนวนมากเนื่องจากUniquifierมีขนาดใหญ่เพียง 4 ไบต์ (จำนวนเต็มพื้นฐาน 32 บิต) ดังนั้นหากระบบของคุณมีการทำงาน CRUD จำนวนมากคุณอาจใช้ตัวเลขที่ไม่ซ้ำกันทั้งหมดและในทันใดคุณจะได้รับข้อผิดพลาดและจะไม่อนุญาตให้คุณแทรกข้อมูลลงในตารางของคุณอีกต่อไป (เพราะจะ ไม่มีค่าที่ไม่ซ้ำกันเพื่อกำหนดให้กับแถวที่คุณเพิ่งแทรกใหม่อีกต่อไป)

เมื่อสิ่งนี้เกิดขึ้นคุณจะได้รับข้อผิดพลาดนี้:

The maximum system-generated unique value for a duplicate group 
was exceeded for index with partition ID (someID). 

Dropping and re-creating the index may resolve this;
otherwise, use another clustering key.

ข้อผิดพลาด 666 (ข้อผิดพลาดด้านบน) เกิดขึ้นเมื่อuniquifierสำหรับชุดคีย์ที่ไม่ซ้ำกันชุดเดียวใช้มากกว่า 2,147,483,647 แถว

ดังนั้นคุณจะต้องมีค่า ~ 2 พันล้านแถวสำหรับค่าคีย์เดียวหรือคุณจะต้องแก้ไขค่าคีย์เดี่ยว ~ 2 พันล้านครั้งเพื่อดูข้อผิดพลาดนี้ ดังนั้นจึงไม่น่าเป็นไปได้มากที่คุณจะได้รับข้อ จำกัด นี้


ฉันไม่รู้ว่าตัวแยกที่ซ่อนอยู่นั้นสามารถวิ่งออกไปจากที่ว่างที่สำคัญได้ แต่ฉันคิดว่าทุกสิ่งมีข้อ จำกัด ในบางกรณี เช่นเดียวกับวิธีCaseและIfโครงสร้างถูก จำกัด ไว้ที่ 10 ระดับมันทำให้รู้สึกว่ายังมีข้อ จำกัด ในการแก้ไขเอนทิตีที่ไม่ซ้ำกัน ตามคำสั่งของคุณฟังดูเหมือนว่าจะมีผลเฉพาะกับกรณีที่คีย์การทำคลัสเตอร์ไม่ซ้ำกัน นี่เป็นปัญหาสำหรับ a Nonclustered Indexหรือถ้าคีย์การทำคลัสเตอร์Uniqueไม่มีปัญหาสำหรับNonclusteredดัชนีหรือไม่?
Solonotix

ดัชนีที่ไม่ซ้ำกันคือ (เท่าที่ฉันรู้) ถูก จำกัด โดยขนาดของประเภทคอลัมน์ (ดังนั้นหากเป็นประเภท BIGINT คุณมี 8bytes เพื่อทำงานกับ) นอกจากนี้ตามเอกสารอย่างเป็นทางการของ microsoft มีสูงสุด 900 ไบต์อนุญาตสำหรับดัชนีคลัสเตอร์และ 1700bytes สำหรับไม่ใช่คลัสเตอร์ (เนื่องจากคุณสามารถมีดัชนีที่ไม่ใช่คลัสเตอร์มากกว่าหนึ่งดัชนีและดัชนีคลัสเตอร์ 1 ดัชนีต่อหนึ่งตาราง) docs.microsoft.com/en-us/sql/sql-server/ …
Chessbrain

1
@Solonotix - uniquifier จากดัชนีคลัสเตอร์ถูกใช้ในดัชนีที่ไม่ใช่คลัสเตอร์ ถ้าคุณเรียกใช้รหัสในตัวอย่างของฉันโดยไม่มีคีย์หลัก (สร้างดัชนีคลัสเตอร์แทน) คุณสามารถดูผลลัพธ์ได้เหมือนกันทั้งดัชนีที่ไม่ซ้ำกันและดัชนีที่ไม่ซ้ำกัน
Max Vernon

-2

ฉันจะไม่ชั่งน้ำหนักในคำถามที่ว่าดัชนีควรจะไม่ซ้ำกันหรือไม่และว่ามีค่าใช้จ่ายมากขึ้นในวิธีการนี้หรือว่า แต่มีบางสิ่งที่รบกวนฉันในการออกแบบทั่วไปของคุณ

  1. dt datetime ไม่ใช่ค่าเริ่มต้น null (current_timestamp) Datetime เป็นรูปแบบที่เก่ากว่าหรือสิ่งนี้และคุณอาจจะสามารถประหยัดพื้นที่ได้อย่างน้อยโดยใช้ datetime2 () และ sysdatetime ()
  2. สร้างดัชนี [nonunique_nonclustered_example] ใน #test_index (is_deleted) include (val) เรื่องนี้ทำให้ฉันรำคาญใจ ลองดูวิธีการเข้าถึงข้อมูล (ฉันเดิมพันมีมากกว่าWHERE is_deleted = 0) และดูโดยใช้ดัชนีที่กรอง ฉันจะพิจารณาใช้ดัชนีที่ผ่านการกรอง 2 รายการดัชนีหนึ่งรายการสำหรับดัชนีwhere is_deleted = 0อื่นwhere is_deleted = 1

พื้นฐานดูเหมือนว่านี่คือแบบฝึกหัดการเข้ารหัสที่ออกแบบมาเพื่อทดสอบสมมุติฐานแทนที่จะเป็นปัญหา / วิธีแก้ปัญหาที่แท้จริง แต่รูปแบบทั้งสองนั้นเป็นสิ่งที่ฉันมองหาในบทวิจารณ์โค้ด


ส่วนใหญ่คุณจะประหยัดโดยใช้ datetime2 แทน datetime คือ 1 ไบต์และนั่นคือถ้าความแม่นยำของคุณน้อยกว่า 3 ซึ่งหมายถึงการสูญเสียความแม่นยำในเสี้ยววินาทีซึ่งไม่ใช่วิธีแก้ปัญหาที่ใช้งานได้เสมอไป สำหรับดัชนีตัวอย่างที่ให้ไว้การออกแบบได้รับการออกแบบให้เรียบง่ายเพื่อให้ความสำคัญกับคำถามของฉัน Nonclusteredดัชนีจะมีคีย์การจัดกลุ่มต่อท้ายแถวข้อมูลสำหรับการค้นหาที่สำคัญภายใน ด้วยเหตุนี้ดัชนีทั้งสองจึงเหมือนกันทางกายภาพซึ่งเป็นประเด็นของคำถามของฉัน
Solonotix

ในระดับที่เราทำงานที่บันทึกไบต์หรือสองเพิ่มขึ้นอย่างรวดเร็ว และฉันสันนิษฐานว่าเนื่องจากคุณใช้ datetime ไม่แม่นยำเราสามารถลดความแม่นยำได้ สำหรับดัชนีอีกครั้งฉันจะระบุคอลัมน์บิตนั้นว่าคอลัมน์นำไปสู่ดัชนีเป็นรูปแบบที่ฉันถือว่าเป็นตัวเลือกที่ไม่ดี ระยะทางของคุณอาจแตกต่างกันไป เป็นข้อเสียของโมเดลโดยประมาณ
Toby

-4

ดูเหมือนว่าคุณเพียงแค่ใช้ PK เพื่อสร้างดัชนีสำรองที่เล็กลง ดังนั้นประสิทธิภาพของมันจึงเร็วขึ้น

คุณเห็นสิ่งนี้ที่ บริษัท ที่มีตารางข้อมูลจำนวนมาก (เช่น: ตารางข้อมูลหลัก) มีคนตัดสินใจที่จะมีดัชนีคลัสเตอร์ขนาดใหญ่หนึ่งรายการโดยคาดว่าจะตอบสนองความต้องการของกลุ่มการรายงานต่างๆ

แต่กลุ่มหนึ่งอาจต้องการเพียงไม่กี่ส่วนของดัชนีนั้นขณะที่อีกกลุ่มหนึ่งต้องการส่วนอื่น .. ดังนั้นดัชนีเพียงตบในทุกคอลัมน์ภายใต้ดวงอาทิตย์เพื่อ "ประสิทธิภาพการเพิ่มประสิทธิภาพ" ไม่ได้ช่วยจริงๆ

ในขณะเดียวกันการทำลายมันลงเพื่อสร้างดัชนีเป้าหมายขนาดเล็กหลาย ๆ ตัวมักจะแก้ปัญหาได้

และดูเหมือนว่าจะเป็นสิ่งที่คุณทำ คุณมีดัชนีคลัสเตอร์ขนาดใหญ่นี้ที่มีประสิทธิภาพแย่มากจากนั้นคุณใช้ PK เพื่อสร้างดัชนีใหม่ที่มีคอลัมน์น้อยลง (ไม่แปลกใจ) ที่มีประสิทธิภาพดีกว่า

ดังนั้นเพียงแค่ทำการวิเคราะห์และหาว่าคุณสามารถใช้ดัชนีกลุ่มเดียวและแยกย่อยออกเป็นดัชนีขนาดเล็กลงซึ่งเป็นเป้าหมายที่งานเฉพาะต้องการได้หรือไม่

คุณจะต้องวิเคราะห์ประสิทธิภาพจากจุดยืน "ดัชนีเดี่ยวกับดัชนีหลายรายการ" เนื่องจากมีค่าใช้จ่ายในการสร้างและอัปเดตดัชนี แต่คุณต้องวิเคราะห์สิ่งนี้จากมุมมองโดยรวม

EG: อาจใช้ทรัพยากรน้อยลงในการทำดัชนีขนาดใหญ่หนึ่งคลัสเตอร์และใช้ทรัพยากรมากขึ้นเพื่อให้มีดัชนีเป้าหมายขนาดเล็กจำนวนมาก แต่ถ้าคุณสามารถเรียกใช้คิวรีเป้าหมายที่แบ็คเอนด์ได้เร็วกว่ามากประหยัดเวลา (และเงิน) ที่นั่นมันอาจคุ้มค่า

ดังนั้นคุณต้องทำการวิเคราะห์แบบ end-to-end .. ไม่เพียงแค่ดูว่ามันส่งผลกระทบต่อโลกของคุณเองอย่างไร แต่มันก็มีผลกระทบต่อผู้ใช้ปลายทางด้วยเช่นกัน

ฉันแค่รู้สึกว่าคุณกำลังใช้ตัวระบุ PK ผิดพลาด แต่คุณอาจใช้ระบบฐานข้อมูลที่อนุญาตเพียง 1 ดัชนี (?) แต่คุณสามารถแอบเข้าไปอีกถ้าคุณ PK (b / c ทุกระบบฐานข้อมูลเชิงสัมพันธ์วันนี้ดูเหมือนว่าจะจัดทำดัชนี PK โดยอัตโนมัติ) อย่างไรก็ตาม RDBMS ที่ทันสมัยส่วนใหญ่ควรอนุญาตให้สร้างดัชนีหลายรายการได้ ไม่ควรมีการ จำกัด จำนวนดัชนีที่คุณสามารถสร้างได้ (ตรงข้ามกับข้อ จำกัด ของ 1 PK)

ดังนั้นการทำ PK whicih เพียงแค่ทำหน้าที่เหมือนกับดัชนี alt .. คุณกำลังใช้ PK ของคุณซึ่งอาจจำเป็นถ้าตารางถูกขยายในบทบาท

ไม่ได้หมายความว่าตารางของคุณไม่จำเป็นต้องใช้ PK .. SOP DB ของ 101 บอกว่า "ทุกตารางควรมี PK" แต่ในสถานการณ์ของ data-warehousing หรือ .. การมี PK บนโต๊ะอาจเป็นค่าใช้จ่ายเพิ่มเติมที่คุณไม่ต้องการ หรืออาจเป็น god-send เพื่อให้แน่ใจว่าคุณไม่ได้เพิ่มรายการ dupe มันเป็นเรื่องของสิ่งที่คุณทำและทำไมคุณถึงทำมัน

แต่ตารางจำนวนมากจะได้ประโยชน์จากการมีดัชนี แต่การสมมติว่าดัชนีคลัสเตอร์ขนาดใหญ่เพียงชุดเดียวจะดีที่สุดก็คือ ... มันอาจจะดีที่สุด .. แต่ฉันขอแนะนำให้ทดสอบการทดสอบ env เพื่อทำลายดัชนีแยกออกเป็นดัชนีขนาดเล็กจำนวนมากที่กำหนดเป้าหมายสถานการณ์การใช้งานเฉพาะ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.