MS sql ինդեքսներ. Sql սերվեր – Կարևորո՞ւմ է պատվերը Microsoft SQL-ում ծածկող ինդեքս ստեղծելիս: Մշտական ​​հաշվարկված սյունակներ

--Ինդեքսը սկավառակի կառուցվածք է, որը կապված է աղյուսակի կամ տեսքի հետ և արագացնում է տողերի հայտնաբերումը աղյուսակից կամ դիտումից: Ցուցանիշը պարունակում է աղյուսակի կամ տեսքի մեկ կամ մի քանի սյուներից կառուցված բանալիներ: Այս բանալիները պահվում են հավասարակշռված ծառի կառուցվածքում, որն աջակցում է տողերի արագ որոնումը՝ ըստ իրենց հիմնական արժեքների SQL Server-ում:

- Կլաստերային ինդեքսները տեսակավորում և պահում են տվյալների տողերը աղյուսակներում կամ դիտումներում՝ հիմնվելով դրանց հիմնական արժեքների վրա: Այս արժեքները ինդեքսի սահմանման մեջ ներառված սյունակներն են: Յուրաքանչյուր աղյուսակում կա միայն մեկ կլաստերային ինդեքս, քանի որ տվյալների տողերը կարող են տեսակավորվել միայն մեկ հերթականությամբ:
-- Աղյուսակում տվյալների տողերը պահվում են տեսակավորման կարգով միայն այն դեպքում, եթե աղյուսակը պարունակում է կլաստերային ինդեքս: Եթե ​​աղյուսակն ունի կլաստերային ինդեքս, ապա աղյուսակը կոչվում է կլաստեր: Եթե ​​աղյուսակը չունի կլաստերային ինդեքս, տվյալների տողերը պահվում են անկանոն կառուցվածքով, որը կոչվում է կույտ:

-- Ոչ կլաստերային ինդեքսն ունի ճիշտ նույն կառուցվածքը, ինչ կլաստերային ինդեքսը, բայց երկու կարևոր տարբերություններով.
-- ոչ կլաստերային ինդեքսը չի փոխում աղյուսակի տողերի ֆիզիկական կարգը, և ոչ կլաստերային ինդեքսի տերևային էջերը բաղկացած են ինդեքսային ստեղներից և էջանիշներից:

--Կլաստերային ինդեքսներն ապահովում են տվյալների ավելի արագ որոնում, քան ոչ կլաստերային ինդեքսները: Նրանք սովորաբար ավելի արագ են դառնում նաև թարմացումների ժամանակ, բայց ոչ այն դեպքում, երբ շատ թարմացումներ տեղի են ունենում նույն տեղում՝ հարաբերությունների կեսին:

- Ինչ-ինչ պատճառներով, կլաստերային ինդեքսը ավելի արագ է աշխատում, քան ոչ կլաստերային ինդեքսը: Երբ համակարգը սկանավորում է կլաստերային ինդեքսը, կարիք չկա թողնել B-tree կառուցվածքը տվյալների էջերը սկանավորելու համար, քանի որ նման էջերն արդեն առկա են ծառի տերևի մակարդակում:

-- Ոչ կլաստերային ինդեքսը նաև պահանջում է ավելի շատ I/O գործողություններ, քան համապատասխան կլաստերային ինդեքսը:

-- Ոչ կլաստերային ինդեքսը պետք է կարդա տվյալների էջերը B-ծառը սկանավորելուց հետո կամ, եթե աղյուսակի մեկ այլ սյունակ(ներ)ում կա խմբավորված ինդեքս, ապա ոչ կլաստերային ինդեքսը պետք է կարդա խմբավորված ինդեքսի B-ծառի կառուցվածքը: .

- Այսպիսով, կլաստերային ինդեքսը զգալիորեն ավելի արագ կլինի, քան աղյուսակի սկանավորումը, նույնիսկ եթե դրա ընտրողականությունը բավականին թույլ է (հարցումը վերադարձնում է շատ տողեր)

ՍՏԵՂԾԵՔ tsql.dbo.NI
ID int NOT NULL,
T char(8) NULL
);

ՍՏԵՂԾԵՔ tsql.dbo.NCI
ID int NOT NULL,
T char(8) NULL
);

-- Ստեղծեք կլաստերային ինդեքս

ՍՏԵՂԾԵԼ ԿԼԱՍՏԵՐ ԻՆԴԵՔՍ IX_1
ON tsql.dbo.NCI (ID);

--Սեղանի վրա ստեղծեք ոչ կլաստերային ինդեքս

ՍՏԵՂԾԵԼ ՈՉ ԿԼՅՈՒՍՏԵՐ ԻԴԵՔՍ IX_2
ON tsql.dbo.NCI (T);

- Ավելացնել թեստի տվյալներ
ՀԱՅՏԱՐԱՐԵԼ @i INT = 100000;
ՀԱՅՏԱՐԱՐԵԼ @t CHAR(1) = «T»;

Մինչդեռ @i > 0
ՍԿՍԵԼ
ներդիր tsql.dbo.NI արժեքների մեջ (@i, @t + CAST(@i AS char(6)));
ներդիր tsql.dbo.NCI արժեքների մեջ (@i, @t + CAST(@i AS char(6)));
SET @i -= 1;
ՎԵՐՋ

-- Հարցումներ աղյուսակի վրա ինդեքսներով
SELECT ID, T FROM tsql.dbo.NCI
ՊԱՏՎԵՐԸ ID-ով, Տ

SELECT ID, COUNT(*) AS C FROM tsql.dbo.NCI
ԽՈՒՄԲ ԸՍՏ ID-ի, Տ

SELECT ID, T FROM tsql.dbo.NCI
ՈՐՏԵՂ ID > 4000 ԵՎ ID< 55000 AND T LIKE "T%"

-- Հարցում` օգտագործելով երկու ինդեքսները
ՕԳՏԱԳՈՐԾԵԼ tsql;
SELECT CAST (dbo.NCI.ID AS VARCHAR)
dbo.NCI-ից
ԽՈՒՄԲ ԸՍՏ dbo.NCI.ID
ՄԻՈՒԹՅՈՒՆ ԲՈԼՈՐ
Ընտրեք dbo.NCI.T
dbo.NCI-ից
ԽՈՒՄԲԸ dbo.NCI.T-ի կողմից

--Ինդեքսի տեղեկատվությունը
SELECT index_type_desc, index_depth, index_level,
page_count, record_count
FROM sys.dm_db_index_physical_stats-ից
(DB_ID(N"tsql"), OBJECT_ID(N"dbo.NCI"), NULL, NULL, "ՄԱՆՐԱՄԱՍԻՐ");

-- Ցուցանիշների ջնջում
ԵԹԵ ԳԿԱ (Ընտրեք անունը sys.indexes-ից
WHERE անունը = N"IX_1")
DROP INDEX IX_1 ON tsql.dbo.NCI;

ԵԹԵ ԳԿԱ (Ընտրեք անունը sys.indexes-ից
WHERE անունը = N"IX_2")
DROP INDEX IX_2 ON tsql.dbo.NCI;

Նախորդ հոդվածում մենք ներկայացրեցինք հարաբերական տվյալների բազաների օպտիմալացման ուղիները և քննարկեցինք, թե ինչպես են աշխատում կլաստերային և ոչ կլաստերային ինդեքսները տվյալների բազայի հարցումների կատարման ժամանակի օպտիմալացման համատեքստում: Այժմ ժամանակն է գործնականում կիրառել այս գիտելիքները՝ սովորելով, թե ինչպես ստեղծել օպտիմալացման ինդեքսներ MS SQL տվյալների բազայի համար:

Թույլ տվեք հիշեցնել ձեզ Staffs աղյուսակի սխեմայի սահմանումը, որի հետ մենք աշխատելու ենք.

Անձնակազմի սեղան

Ենթադրենք, որ մենք պետք է ստեղծենք ոչ կլաստերային ինդեքս Staffs աղյուսակի համար, որը կօպտիմալացնի հետևյալ հարցումը.

ԸՆՏՐԵՔ ID-ն, Անունը, Աշխատանքը այն իրերից, որտեղ աշխատավարձը > 1000 և լուսանկարը զրոյական չէ

Ինդեքսի բանալին կլինի ԱՇԽԱՏԱՎԱՐՁԸ և Լուսանկարը սյունակները, քանի որ ընտրությունը զտված է այս դաշտերով: Իսկ Id, Name և Job սյունակները կլինեն ինդեքսում ներառված սյունակները։

Ընդհանուր հրամանի շարահյուսությունը հետևյալն է.

ՕԳՏԱԳՈՐԾԵԼ ԳՆԱՑԵՔ

ՍՏԵՂԾԵԼ ՈՉ ԿԼԱՍՏԵՐ ԻԴԵՔՍ ՎՐԱ (ASC - ինդեքսային բանալի սյունակներ)

ՆԵՐԱՌՈՒՄ ( -- ներառված սյունակներ) GO

Մեր դեպքում հարցումը կունենա հետևյալ տեսքը.

(Աշխատավարձը, Լուսանկարը) ՆԵՐԱՌՈՒՄ (Id, Անուն, Աշխատանք) ԳՆԱԼ

Մենք ստեղծել ենք ոչ կլաստերային ինդեքս։ Ավելի ճիշտ՝ ոչ կլաստերային ծածկույթի ինդեքս։ Սա նշանակում է, որ ինդեքսը պարունակում է բոլոր դաշտերը, որոնք անհրաժեշտ են հարցումը կատարելու համար, և SQL Server-ը չի մուտքի բազային աղյուսակը հարցումն իրականացնելիս:

Եթե ​​մեր կոդը այսպիսին լիներ.

ՍՏԵՂԾԵԼ ՈՉ ԿԼՅՈՒՍՏԵՐ ԻԴԵՔՍ IDX_StaffsSearch ON Stuffs

(Աշխատավարձ, Լուսանկար) ՆԵՐԱՌՈՒՄ (Id) GO

Այս դեպքում ինդեքսը դադարում է լինել ծածկող ինդեքս, քանի որ այն չի ներառում հարցումում օգտագործված բոլոր սյունակները։ Օպտիմիզատորը դեռ կօգտագործի այս ցուցանիշը հարցումն իրականացնելիս, սակայն դրա արդյունավետությունը կնվազի մեծության կարգով, քանի որ այն կպահանջի մուտք դեպի բազային աղյուսակ:

Կլաստերային ինդեքսը ստեղծվում է հետևյալ հրամանի միջոցով.

ՍՏԵՂԾԵԼ ԿԼՅՈՒՍՏԵՐ ԻՆԴԵՔՍ IDX_Stsffsid ON իրերի վրա (ID)

Այստեղ ստեղծվել է եզակի կլաստերային ինդեքս՝ հիմնվելով աղյուսակի հիմնական բանալի վրա (Id սյունակ):

Իրական օրինակ

Եկեք այժմ մշակենք մի սցենար, որտեղ մենք կարող ենք իրատեսորեն գնահատել կատարողականի բարձրացման աստիճանը ինդեքսների օգտագործման դեպքում:

Եկեք ստեղծենք նոր տվյալների բազա.

Ստեղծել տվյալների բազա TestDB;

Եվ մեկ Հաճախորդների աղյուսակ, որը բաղկացած կլինի չորս սյունակից.

ՍԵՂԱՆԱԿ ՍՏԵՂԾԵԼ .(

NOT NULL, NULL, NULL, NULL) ԳՆԱԼ

Հիմա եկեք լրացնենք մեր աղյուսակը պատահական տվյալներով։ Id սյունակը կավելացվի ցիկլով, իսկ աղյուսակի մնացած երեք սյունակները կլցվեն պատահական թվերով՝ օգտագործելով պատահական ֆունկցիայի յուրահատուկ տարբերակը.

ՀԱՅՏԱՐԱՐԵԼ @i int = 0;

Մինչդեռ (@i< 500000) BEGIN INSERT INTO Customers(Id, Num1, Num2, Num3) VALUES(

@i, abs(checksum(newid())), abs(checksum(newid())), abs(checksum(newid())) SET @i = @i + 1; ՎԵՐՋ

Այս սցենարը սեղանին ավելացնում է կես միլիոն ձայնագրություն, այնպես որ համբերատար եղեք, սցենարը կաշխատի առնվազն 3 րոպե:

Ամեն ինչ պատրաստ է թեստի համար։ Մենք կգնահատենք հարցման կատարողական բնութագրերը: Քանի որ հարցման կատարման ժամանակը կարող է կախված լինել կոնկրետ մեքենայից, մենք կվերլուծենք ավելի անկախ ցուցանիշ՝ տրամաբանական ընթերցումների քանակը:

Վիճակագրության հավաքագրման ռեժիմը միացնելու համար դուք պետք է գործարկեք հետևյալ հրամանը.

Այժմ, յուրաքանչյուր հարցում կատարելուց հետո, «Հաղորդագրություններ» ներդիրում մենք մուտք կունենանք այս հարցման կատարման վիճակագրությանը, ինչպես ցույց է տրված ստորև.

Մեզ հետաքրքրում է միայն տրամաբանական ընթերցումների պարամետրի արժեքը:

Այսպիսով, մեր աղյուսակում դեռ ինդեքսներ չկան։ Եկեք կատարենք հետևյալ երեք հարցումները և գրանցենք յուրաքանչյուր հարցման տրամաբանական ընթերցումների քանակը ստորև բերված արդյունքների աղյուսակում.

1) SELECT Id, Num1, Num2 FROM Customers WHERE Id = 2000

2) SELECT Id, Num1, Num2 FROM Customers WHERE Id >= 0 AND Id< 1000

3) SELECT Id, Num1, Num2 FROM Customers WHERE Id >= 0 AND Id< 5000

Այս հարցումները կվերադարձնեն համապատասխանաբար 1 տող, 1000 տող և 5000 տող: Առանց ինդեքսների, կատարողականի ցուցանիշը (տրամաբանական ընթերցումների քանակը) բոլոր հարցումների համար նույնն է և հավասար է 1621-ի: Եկեք տվյալները մուտքագրենք արդյունքների աղյուսակում.

Մենք տեսնում ենք, որ երկրորդ և երրորդ հարցումների դեպքում, երբ վերադարձվում են բավականին մեծ թվով տողեր, մեր ստեղծած ինդեքսը չի բարելավել կատարողականը: Այնուամենայնիվ, հարցման համար, որը վերադարձնում է մեկ տող, արագությունը հսկայական էր: Այսպիսով, մենք կարող ենք եզրակացնել, որ իմաստ ունի ստեղծել ոչ ծածկող ինդեքսներ, երբ օպտիմալացնելով հարցումները, որոնք վերադարձնում են մեկ արդյունք:

Այժմ եկեք ստեղծենք ծածկույթի ինդեքս՝ դրանով իսկ հասնելով առավելագույն կատարողականության։

Նախ, եկեք ջնջենք նախորդ ցուցանիշը.

ՕԳՏԱԳՈՐԾԵԼ TestDB GO DROP INDEX Customers.TestIndex1

Եվ եկեք ստեղծենք նոր ինդեքս.

ՍՏԵՂԾԵԼ ՈՉ ԿԼԱՍՏԵՐ ԻՆԴԵՔՍ TestIndex2 ON dbo.Customers(Id) INCLUDE (Num1, Num2);

Հիմա եկեք երրորդ անգամ կատարենք մեր հարցումները և արդյունքները գրենք աղյուսակում.

Ցուցանիշներ չկան

Ոչ ծածկող ինդեքս

Ծածկույթի ինդեքս

Հեշտ է տեսնել, որ կատարողականի աճը հսկայական է եղել: Այսպիսով, մենք տասնյակ անգամ ավելացրել ենք հարցումների կատարման արագությունը։ Միլիոնավոր տողեր պահող տվյալների շտեմարան գործարկելիս այս կատարողականի ձեռքբերումը բավականին նկատելի կլինի:

Այս հոդվածում մենք դիտարկեցինք տվյալների բազայի օպտիմալացման օրինակ՝ ստեղծելով ինդեքսներ: Հարկ է նշել, որ ինդեքսների ստեղծումը զուտ անհատական ​​գործընթաց է յուրաքանչյուր հարցման համար: Ինդեքս ստեղծելու համար, որն իսկապես կօպտիմալացնի հարցումների կատարումը, դուք պետք է ուշադիր վերլուծեք հարցումը և դրա կատարման պլանը:

Արդյունավետ ինդեքսի ստեղծումը տվյալների բազայի հավելվածի արդյունավետությունը բարելավելու լավագույն միջոցներից մեկն է: Առանց ինդեքսների օգտագործման, SQL Server-ը նման է ընթերցողի, որը փորձում է գրքում որևէ բառ գտնել՝ նայելով յուրաքանչյուր էջ: Եթե ​​գիրքն ունի առարկայական ինդեքս (ինդեքս), ապա ընթերցողը կարող է շատ ավելի արագ փնտրել անհրաժեշտ տեղեկատվությունը։

Ինդեքսի բացակայության դեպքում SQL սերվերը, երբ աղյուսակից տվյալներ է վերցնում, կսկանավորի ամբողջ աղյուսակը և կստուգի յուրաքանչյուր տող՝ տեսնելու, թե արդյոք բավարարված են հարցման չափանիշները: Նման ամբողջական սկանավորումը կարող է աղետալի լինել ամբողջ համակարգի աշխատանքի համար, հատկապես, եթե աղյուսակներում շատ տվյալներ կան:

Տվյալների բազայի հետ աշխատելիս ամենակարևոր խնդիրներից մեկը օպտիմալ ինդեքսի ստեղծումն է՝ համակարգի արդյունավետությունը բարելավելու համար: Հիմնական տվյալների բազաներից շատերը տրամադրում են գործիքներ՝ հարցումների կատարման պլանը դիտելու և օգնելու ձեզ կարգավորել և օպտիմալացնել ինդեքսները: Այս հոդվածը ընդգծում է մի քանի լավ կանոններ, որոնք կիրառվում են տվյալների բազայում ինդեքսներ ստեղծելիս կամ փոփոխելիս: Նախ, եկեք նայենք իրավիճակներին, երբ ինդեքսավորումը բարելավում է կատարողականությունը, և որտեղ ինդեքսավորումը կարող է վնասել:

Օգտակար ցուցանիշներ

Այսպիսով, աղյուսակի ինդեքսավորումը օգտակար կլինի աղյուսակում կոնկրետ գրառում փնտրելիս՝ օգտագործելով Where հայտարարությունը: Նման հարցումները ներառում են, օրինակ, հարցումներ, որոնք որոնում են մի շարք արժեքներ, հարցումներ, որոնք համապատասխանում են ճշգրիտ արժեքին որոշակի արժեքին, և հարցումները, որոնք միավորում են երկու աղյուսակներ:

Օրինակ, Northwind տվյալների բազայի վերաբերյալ հետևյալ հարցումները ավելի արդյունավետ կաշխատեն UnitPrice սյունակի վրա ինդեքս կառուցելիս:

Ջնջել այն ապրանքներից, որտեղ UnitPrice=1
Ընտրեք * ապրանքներից, որտեղ միավորի գինը 14-ից 16-ի միջև է

Քանի որ ինդեքսային տարրերը պահվում են տեսակավորված, ինդեքսավորումը նույնպես օգտակար է հարցում կառուցելիս՝ օգտագործելով «Պատվերն ըստ կետի»: Առանց ինդեքսի, գրառումները բեռնվում և տեսակավորվում են, մինչ հարցումն աշխատում է: UnitPrice-ի վրա հիմնված ինդեքսը թույլ կտա ձեզ պարզապես սկանավորել ինդեքսը և հաջորդ հարցումը մշակելիս առբերել տողերը հղումով: Եթե ​​ցանկանում եք դասավորել տողերը նվազման կարգով, կարող եք պարզապես սկանավորել ինդեքսը հակառակ հերթականությամբ:

Ընտրեք * Ապրանքների պատվերից ըստ UnitPrice ASC-ի

Գրառումների խմբավորումը՝ օգտագործելով Group-ը ըստ հայտարարության, նույնպես հաճախ պահանջում է տեսակավորում, այնպես որ UnitPrice սյունակում ինդեքս կառուցելը նույնպես օգտակար կլինի հաջորդ հարցման համար, որը հաշվում է ապրանքի միավորների քանակը յուրաքանչյուր կոնկրետ գնով:

Ընտրեք count(*), UnitPrice From Products Group by UnitPrice

Ինդեքսներն օգտակար են սյունակի համար եզակի արժեք պահելու համար, քանի որ DBMS-ը կարող է հեշտությամբ նայել ինդեքսին՝ տեսնելու, թե արդյոք արժեքը արդեն գոյություն ունի: Այս պատճառով առաջնային բանալիները միշտ ինդեքսավորվում են:

Ինդեքսավորման թերությունները

Ինդեքսները նվազեցնում են համակարգի աշխատանքը ռեկորդային փոփոխությունների ժամանակ: Ամեն անգամ, երբ հարցումը կատարվում է աղյուսակում տվյալները փոխելու համար, ինդեքսը նույնպես պետք է փոխվի: Ինդեքսների օպտիմալ քանակն ընտրելու համար անհրաժեշտ է փորձարկել տվյալների բազան և վերահսկել դրա կատարումը: Ստատիկ համակարգերը, որտեղ տվյալների բազաները հիմնականում օգտագործվում են տվյալների որոնման համար, ինչպիսին է հաշվետվությունները, կարող են պարունակել ավելի շատ ինդեքսներ՝ միայն կարդալու հարցումներին աջակցելու համար: Տվյալները փոխելու համար մեծ թվով գործարքներ ունեցող տվյալների բազաներին անհրաժեշտ կլինի փոքր թվով ինդեքսներ՝ ավելի բարձր թողունակություն ապահովելու համար:

Ինդեքսները լրացուցիչ տեղ են զբաղեցնում սկավառակի վրա և RAM-ում: Ճշգրիտ չափը կախված կլինի աղյուսակի գրառումների քանակից, ինչպես նաև ինդեքսի սյունակների քանակից և չափից: Շատ դեպքերում դա լուրջ խնդիր չէ, քանի որ սկավառակի տարածությունն այժմ հեշտ է զոհաբերել ավելի լավ կատարման համար:

Օպտիմալ ինդեքսի կառուցում

Պարզ ցուցանիշ

Պարզ ինդեքսը ինդեքս է, որն օգտագործում է աղյուսակի մեկ դաշտի արժեքները: Պարզ ինդեքսի օգտագործումը շահավետ է երկու պատճառով. Նախ, տվյալների բազայի գործարկումը մեծ սթրես է դնում ձեր կոշտ սկավառակի վրա: Մեծ ինդեքսային ստեղները կստիպի տվյալների բազան կատարել ավելի շատ I/O գործողություններ, ինչը սահմանափակում է կատարումը:

Երկրորդ, քանի որ ինդեքսի տարրերը հաճախ ներգրավված են համեմատությունների մեջ, ավելի փոքր ինդեքսներն ավելի հեշտ են համեմատել: Այս երկու պատճառով, մեկ ամբողջ թիվ սյունակը ավելի լավ ցուցանիշ է, քանի որ այն փոքր է և հեշտ է համեմատել: Մյուս կողմից, նիշերի տողերը պահանջում են նիշ առ նիշ համեմատություններ և ուշադրություն պարամետրերի մշակման նկատմամբ:

Ընտրովի ինդեքս

Ամենաարդյունավետ ինդեքսներն են կրկնօրինակ արժեքների ցածր տոկոսով: Օրինակ, հեռախոսային գրացուցակը մի քաղաքի համար, որտեղ գրեթե բոլորն ունեն Սմիթ ազգանունը, այնքան էլ օգտակար չի լինի, եթե այնտեղ գրառումները դասավորված լինեն ազգանունով:

Եզակի արժեքների բարձր տոկոս ունեցող ինդեքսը կոչվում է նաև ընտրովի ինդեքս: Ակնհայտ է, որ եզակի ինդեքսն ունի ամենամեծ ընտրողականությունը, քանի որ այն չի պարունակում կրկնօրինակ արժեքներ: Շատ DBMS-ներ կարող են հետևել յուրաքանչյուր ինդեքսի վիճակագրությանը և կարող են ճանաչել, թե յուրաքանչյուր ինդեքս քանի ոչ կրկնօրինակ արժեք է պարունակում: Այս վիճակագրությունը օգտագործվում է հարցումների կատարման պլան ստեղծելիս:

Ծածկման ինդեքսներ

Ինդեքսները բաղկացած են տվյալների սյունակից, որի վրա կառուցված է հենց ինդեքսը և համապատասխան տողի ցուցիչը: Դա նման է գրքի ինդեքսին. այն պարունակում է միայն հիմնաբառեր և հղում դեպի էջի, որտեղ կարող եք գնալ լրացուցիչ տեղեկությունների համար: Սովորաբար DBMS-ը հետևում է ցուցիչներին դեպի ինդեքսից տող՝ հարցման համար անհրաժեշտ ողջ տեղեկատվությունը հավաքելու համար: Այնուամենայնիվ, եթե ինդեքսը պարունակում է հարցման համար անհրաժեշտ բոլոր սյունակները, ապա տեղեկատվությունը կարող է առբերվել առանց աղյուսակին մուտք գործելու:

Դիտարկենք UnitPrice սյունակի ինդեքսը, որն արդեն նշվել է վերևում: DBMS-ը կարող է օգտագործել միայն ինդեքսի տարրերը հաջորդ հարցումը կատարելու համար:

Ընտրեք Count(*), UnitPrice From Products Group by UnitPrice

Հարցման այս տեսակը կոչվում է ծածկող հարցում, քանի որ հարցվող բոլոր սյունակները կարող են վերցվել մեկ ինդեքսից: Ամենակարևոր հարցումների համար կարող եք մտածել ծածկող ինդեքս ստեղծելու հնարավոր լավագույն կատարման համար: Նման ինդեքսները, ամենայն հավանականությամբ, կլինեն կոմպոզիտային (օգտագործելով մեկից ավելի սյունակ), ինչը առաջին սկզբունքի հակառակն է՝ ստեղծել պարզ ինդեքսներ: Ակնհայտ է, որ ինդեքսի սյունակների օպտիմալ քանակի ընտրությունը կարող է գնահատվել միայն տարբեր իրավիճակներում տվյալների բազայի աշխատանքի փորձարկման և մոնիտորինգի միջոցով:

Կլաստերային ինդեքս

Շատ տվյալների բազաներ ունեն մեկ հատուկ ինդեքս սեղանի վրա, որտեղ մի շարքի բոլոր տվյալները պարունակվում են ինդեքսում: SQL Server-ում նման ինդեքսը կոչվում է կլաստերային ինդեքս: Կլաստերային ինդեքսը կարելի է համեմատել հեռախոսային գրացուցակի հետ, քանի որ յուրաքանչյուր ինդեքսի տարր պարունակում է ձեզ անհրաժեշտ բոլոր տեղեկությունները և չի պարունակում լրացուցիչ տվյալներ ստանալու հղումներ:

Գոյություն ունի ընդհանուր կանոն՝ յուրաքանչյուր ոչ տրիվիալ աղյուսակ պետք է ունենա կլաստերային ինդեքս: Եթե ​​սեղանի վրա հնարավոր է ստեղծել միայն մեկ ինդեքս, ապա այն դարձրեք կլաստեր: SQL Server-ում, երբ ստեղծվում է առաջնային բանալի, ավտոմատ կերպով կստեղծվի կլաստերային ինդեքս (եթե այն արդեն չի պարունակում), օգտագործելով հիմնական բանալին սյունակը որպես ինդեքսավորման բանալի: Կլաստերային ինդեքսը ամենաարդյունավետ ինդեքսն է (եթե օգտագործվում է, այն ընդգրկում է ամբողջ հարցումը) և շատ DBMS-ներում նման ինդեքսն օգնում է արդյունավետորեն կառավարել աղյուսակները պահելու համար պահանջվող տարածքը, քանի որ հակառակ դեպքում (առանց կլաստերային ինդեքս կառուցելու) աղյուսակի տողերը պահվում են. չկարգավորված կառույց, որը կոչվում էր կույտ:

Զգույշ եղեք կլաստերային ինդեքսի համար սյունակներ ընտրելիս: Եթե ​​դուք փոխեք գրառումը և փոխեք սյունակի արժեքը կլաստերային ինդեքսում, տվյալների բազան ստիպված կլինի վերակառուցել ինդեքսի տարրերը (դրանք տեսակավորված կարգով պահելու համար): Հիշեք, որ կլաստերային ինդեքսի ինդեքսային տարրերը պարունակում են սյունակի բոլոր արժեքները, ուստի սյունակի արժեքի փոփոխությունը համեմատելի է Delete-ի կատարման հետ, որին հաջորդում է Insert-ը, որն ակնհայտորեն կառաջացնի կատարողականի խնդիրներ, եթե դա հաճախ արվի: Այս պատճառով, կլաստերային ինդեքսները հաճախ բաղկացած են առաջնային բանալիից և օտար բանալի սյունակից: Եթե ​​հիմնական արժեքները փոխվում են, դրանք շատ հազվադեպ են փոխվում:

Եզրակացություն

Տվյալների բազայում օգտագործելու համար ճիշտ ինդեքսների որոշումը պահանջում է համակարգի մանրակրկիտ վերլուծություն և փորձարկում: Այս հոդվածում ներկայացված պրակտիկան լավ կանոններ է ինդեքսների կառուցման համար: Այս մեթոդները կիրառելուց հետո ձեզ հարկավոր է վերստուգել ձեր հատուկ հավելվածը ձեր հատուկ սարքաշարի, հիշողության և գործառնական պայմանների ներքո:

Բարձր արտադրողականության հասնելու ամենակարևոր ուղիներից մեկը SQL Serverինդեքսների օգտագործումն է։ Ցուցանիշն արագացնում է հարցումների գործընթացը՝ ապահովելով արագ մուտք դեպի աղյուսակի տվյալների տողեր, ինչպես որ գրքի ինդեքսն օգնում է ձեզ արագ գտնել ձեզ անհրաժեշտ տեղեկատվությունը: Այս հոդվածում ես կտամ ինդեքսների համառոտ ակնարկ SQL Serverև բացատրել, թե ինչպես են դրանք կազմակերպված տվյալների բազայում և ինչպես են դրանք օգնում արագացնել տվյալների բազայի հարցումները:

Ցուցանիշները ստեղծվում են աղյուսակի և դիտման սյունակների վրա: Ինդեքսները հնարավորություն են տալիս արագ որոնել տվյալներ՝ հիմնված այդ սյունակներում առկա արժեքների վրա: Օրինակ, եթե դուք ինդեքս եք ստեղծում առաջնային բանալիի վրա և այնուհետև որոնում եք տվյալների տող՝ օգտագործելով հիմնական բանալիների արժեքները, ապա SQL Serverնախ կգտնի ինդեքսի արժեքը, այնուհետև կօգտագործի ինդեքսը՝ տվյալների ամբողջ շարքը արագ գտնելու համար: Առանց ինդեքսի, աղյուսակի բոլոր տողերի ամբողջական սկանավորումը կկատարվի, ինչը կարող է էական ազդեցություն ունենալ կատարողականի վրա:
Դուք կարող եք ինդեքս ստեղծել աղյուսակի կամ տեսքի սյունակների մեծ մասի վրա: Բացառություն են հիմնականում խոշոր օբյեկտների պահպանման համար տվյալների տեսակներով սյունակները ( ԼՈԲ), ինչպիսիք են պատկեր, տեքստըկամ varchar (առավելագույնը). Դուք կարող եք նաև ինդեքսներ ստեղծել սյունակների վրա, որոնք նախատեսված են տվյալների ձևաչափով պահելու համար XML, բայց այս ցուցանիշները մի փոքր այլ կերպ են կառուցված, քան ստանդարտները, և դրանց քննարկումը դուրս է այս հոդվածի շրջանակներից: Բացի այդ, հոդվածը չի քննարկում սյունակատունցուցանիշները։ Փոխարենը, ես կենտրոնանում եմ այն ​​ինդեքսների վրա, որոնք առավել հաճախ օգտագործվում են տվյալների բազաներում SQL Server.
Ինդեքսը բաղկացած է մի շարք էջերից, ինդեքսային հանգույցներից, որոնք կազմակերպված են ծառի կառուցվածքով. հավասարակշռված ծառ. Այս կառուցվածքն իր բնույթով հիերարխիկ է և սկսվում է հիերարխիայի վերևում գտնվող արմատային հանգույցից և տերևային հանգույցներից, տերևներից, ներքևում, ինչպես ցույց է տրված նկարում.


Երբ հարցում եք անում ինդեքսավորված սյունակում, հարցման շարժիչը սկսվում է արմատային հանգույցի վերևից և իր ճանապարհն անցնում է միջանկյալ հանգույցների միջով, ընդ որում յուրաքանչյուր միջանկյալ շերտ պարունակում է ավելի մանրամասն տեղեկատվություն տվյալների մասին: Հարցման շարժիչը շարունակում է շարժվել ինդեքսային հանգույցներով, մինչև այն հասնի ինդեքսի տերևների ներքևի մակարդակին: Օրինակ, եթե դուք փնտրում եք 123 արժեքը ինդեքսավորված սյունակում, հարցման շարժիչը նախ կորոշի էջը առաջին միջանկյալ մակարդակում՝ արմատային մակարդակում: Այս դեպքում առաջին էջը մատնանշում է 1-ից մինչև 100 արժեք, իսկ երկրորդը՝ 101-ից մինչև 200, ուստի հարցումների շարժիչը կմտնի այս միջանկյալ մակարդակի երկրորդ էջը: Հաջորդը կտեսնեք, որ դուք պետք է դիմեք հաջորդ միջանկյալ մակարդակի երրորդ էջին: Այստեղից հարցման ենթահամակարգը ինքնին կկարդա ինդեքսի արժեքը ավելի ցածր մակարդակում: Ինդեքսի տերևները կարող են պարունակել կա՛մ աղյուսակի տվյալներ, կա՛մ պարզապես ցուցիչ դեպի աղյուսակի տվյալներ ունեցող տողեր՝ կախված ինդեքսի տեսակից՝ կլաստերային ինդեքս կամ ոչ կլաստերային ինդեքս:

Կլաստերային ինդեքս
Կլաստերային ինդեքսը պահում է տվյալների իրական տողերը ինդեքսի տերևներում: Վերադառնալով նախորդ օրինակին, սա նշանակում է, որ 123-ի հիմնական արժեքի հետ կապված տվյալների շարքը կպահվի հենց ինդեքսում: Կլաստերային ինդեքսի կարևոր հատկանիշն այն է, որ բոլոր արժեքները դասավորված են որոշակի հերթականությամբ՝ աճման կամ նվազման: Հետևաբար, աղյուսակը կամ տեսքը կարող է ունենալ միայն մեկ կլաստերային ինդեքս: Բացի այդ, պետք է նշել, որ աղյուսակի տվյալները պահվում են տեսակավորված ձևով միայն այն դեպքում, եթե այս աղյուսակում ստեղծվել է կլաստերային ինդեքս։
Աղյուսակը, որը չունի կլաստերային ինդեքս, կոչվում է կույտ:
Ոչ կլաստերային ինդեքս
Ի տարբերություն կլաստերային ինդեքսի, ոչ կլաստերային ինդեքսի տերևները պարունակում են միայն այդ սյունակները ( բանալի), որով որոշվում է այս ինդեքսը, ինչպես նաև պարունակում է ցուցիչ դեպի աղյուսակի իրական տվյալներ ունեցող տողեր։ Սա նշանակում է, որ ենթհարցման համակարգը պահանջում է լրացուցիչ գործողություն՝ անհրաժեշտ տվյալները գտնելու և առբերելու համար: Տվյալների ցուցիչի բովանդակությունը կախված է նրանից, թե ինչպես են տվյալները պահվում՝ կլաստերային աղյուսակ կամ կույտ: Եթե ​​ցուցիչը ցույց է տալիս կլաստերացված աղյուսակը, այն ցույց է տալիս կլաստերային ինդեքս, որը կարող է օգտագործվել իրական տվյալները գտնելու համար: Եթե ​​ցուցիչը վերաբերում է կույտին, ապա այն մատնանշում է կոնկրետ տվյալների տողի նույնացուցիչ: Ոչ կլաստերային ինդեքսները չեն կարող դասավորվել ինչպես կլաստերային ինդեքսները, բայց դուք կարող եք ստեղծել մեկից ավելի ոչ կլաստերային ինդեքս աղյուսակի կամ դիտման վրա՝ մինչև 999: Սա չի նշանակում, որ դուք պետք է հնարավորինս շատ ինդեքսներ ստեղծեք: Ինդեքսները կարող են կա՛մ բարելավել, կա՛մ վատթարացնել համակարգի աշխատանքը: Բացի այն, որ կարող եք ստեղծել բազմաթիվ ոչ կլաստերային ինդեքսներ, դուք կարող եք նաև ներառել լրացուցիչ սյունակներ ( ներառված սյունակ) իր ինդեքսում. ինդեքսի տերևները կպահեն ոչ միայն ինդեքսավորված սյունակների արժեքը, այլև այդ չինդեքսավորված լրացուցիչ սյունակների արժեքները: Այս մոտեցումը թույլ կտա շրջանցել ինդեքսի վրա դրված որոշ սահմանափակումներ։ Օրինակ, դուք կարող եք ներառել ոչ ինդեքսավորվող սյունակ կամ շրջանցել ինդեքսի երկարության սահմանը (շատ դեպքերում 900 բայթ):

Ինդեքսների տեսակները

Բացի կլաստերային կամ ոչ կլաստերային ինդեքս լինելուց, այն կարող է հետագայում կազմաձևվել որպես կոմպոզիտային ինդեքս, եզակի ինդեքս կամ ծածկող ինդեքս:
Կոմպոզիտային ինդեքս
Նման ցուցանիշը կարող է պարունակել մեկից ավելի սյունակ: Դուք կարող եք ներառել մինչև 16 սյունակ ինդեքսի մեջ, սակայն դրանց ընդհանուր երկարությունը սահմանափակվում է 900 բայթով: Ե՛վ կլաստերային, և՛ ոչ կլաստերային ինդեքսները կարող են լինել կոմպոզիտային:
Եզակի ցուցանիշ
Այս ցուցանիշը ապահովում է, որ ինդեքսավորված սյունակում յուրաքանչյուր արժեք եզակի է: Եթե ​​ինդեքսը կոմպոզիտային է, ապա եզակիությունը վերաբերում է ինդեքսի բոլոր սյունակներին, բայց ոչ յուրաքանչյուր առանձին սյունակի: Օրինակ, եթե դուք ստեղծեք եզակի ինդեքս սյունակների վրա ԱՆՈՒՆԵվ ԱԶԳԱՆՈՒՆ, ապա լրիվ անունը պետք է լինի եզակի, բայց հնարավոր են կրկնօրինակներ անվան կամ ազգանվան մեջ։
Եզակի ինդեքսը ավտոմատ կերպով ստեղծվում է, երբ դուք սահմանում եք սյունակի սահմանափակում՝ առաջնային բանալի կամ եզակի արժեքի սահմանափակում.
  • Առաջնային բանալին
    Երբ դուք սահմանում եք հիմնական բանալի սահմանափակում մեկ կամ մի քանի սյունակների վրա, ապա SQL Serverինքնաբերաբար ստեղծում է եզակի կլաստերային ինդեքս, եթե նախկինում խմբավորված ինդեքս չի ստեղծվել (այս դեպքում առաջնային բանալին ստեղծվում է եզակի ոչ կլաստերային ինդեքս)
  • Արժեքների յուրահատկություն
    Երբ դուք սահմանափակում եք սահմանում արժեքների եզակիության վրա, ապա SQL Serverավտոմատ կերպով ստեղծում է եզակի ոչ կլաստերային ինդեքս: Դուք կարող եք նշել, որ ստեղծվի եզակի կլաստերային ինդեքս, եթե աղյուսակում դեռևս խմբավորված ինդեքս չի ստեղծվել:
Ծածկույթի ինդեքս
Նման ինդեքսը թույլ է տալիս կոնկրետ հարցումին անմիջապես ստանալ բոլոր անհրաժեշտ տվյալները ինդեքսի տերևներից՝ առանց աղյուսակի գրառումների լրացուցիչ մուտքի։

Ինդեքսների նախագծում

Որքան էլ ինդեքսները կարող են օգտակար լինել, դրանք պետք է զգույշ մշակվեն: Քանի որ ինդեքսները կարող են զգալի սկավառակի տարածություն գրավել, դուք չեք ցանկանում ստեղծել ավելի շատ ինդեքսներ, քան անհրաժեշտ է: Բացի այդ, ինդեքսները ինքնաբերաբար թարմացվում են, երբ ինքնին տվյալների շարքը թարմացվում է, ինչը կարող է հանգեցնել լրացուցիչ ռեսուրսների վերին ծախսերի և կատարողականի վատթարացման: Ինդեքսները նախագծելիս պետք է հաշվի առնել մի քանի նկատառումներ՝ կապված տվյալների բազայի և դրա դեմ ուղղված հարցումների հետ:
Տվյալների բազա
Ինչպես նշվեց ավելի վաղ, ինդեքսները կարող են բարելավել համակարգի աշխատանքը, քանի որ նրանք հարցումների շարժիչին ապահովում են տվյալներ գտնելու արագ եղանակով: Այնուամենայնիվ, դուք պետք է նաև հաշվի առնեք, թե որքան հաճախ եք մտադրվում տեղադրել, թարմացնել կամ ջնջել տվյալները: Երբ դուք փոխում եք տվյալները, ինդեքսները նույնպես պետք է փոխվեն, որպեսզի արտացոլեն տվյալների վրա համապատասխան գործողությունները, ինչը կարող է զգալիորեն նվազեցնել համակարգի աշխատանքը: Ձեր ինդեքսավորման ռազմավարությունը պլանավորելիս հաշվի առեք հետևյալ ուղեցույցները.
  • Հաճախակի թարմացվող աղյուսակների համար օգտագործեք որքան հնարավոր է քիչ ինդեքսներ:
  • Եթե ​​աղյուսակը պարունակում է մեծ քանակությամբ տվյալներ, բայց փոփոխությունները աննշան են, ապա օգտագործեք այնքան ինդեքս, որքան անհրաժեշտ է ձեր հարցումների կատարումը բարելավելու համար: Այնուամենայնիվ, փոքր սեղանների վրա ինդեքսներ օգտագործելուց առաջ լավ մտածեք, քանի որ... Հնարավոր է, որ ինդեքսի որոնման օգտագործումը կարող է ավելի երկար տևել, քան պարզապես սկանավորել բոլոր տողերը:
  • Կլաստերային ինդեքսների համար փորձեք դաշտերը հնարավորինս կարճ պահել: Լավագույն մոտեցումը կլաստերային ինդեքս օգտագործելն է սյունակների վրա, որոնք ունեն եզակի արժեքներ և թույլ չեն տալիս NULL: Ահա թե ինչու առաջնային բանալին հաճախ օգտագործվում է որպես կլաստերային ինդեքս:
  • Սյունակի արժեքների եզակիությունը ազդում է ինդեքսի կատարողականի վրա: Ընդհանուր առմամբ, որքան ավելի շատ կրկնօրինակներ ունեք սյունակում, այնքան վատ է ցուցանիշը կատարում: Մյուս կողմից, որքան շատ եզակի արժեքներ լինեն, այնքան ավելի լավ կլինի ցուցանիշի կատարումը: Հնարավորության դեպքում օգտագործեք եզակի ինդեքս:
  • Կոմպոզիտային ինդեքսի համար հաշվի առեք ինդեքսի սյունակների հերթականությունը: Սյունակներ, որոնք օգտագործվում են արտահայտություններում ՈՐՏԵՂ(Օրինակ, WHERE FirstName = «Չարլի») պետք է լինի առաջինը ինդեքսում: Հետագա սյունակները պետք է թվարկվեն՝ ելնելով դրանց արժեքների եզակիությունից (առաջին տեղում են ամենաշատ եզակի արժեքներով սյունակները):
  • Դուք կարող եք նաև նշել ինդեքսը հաշվարկված սյունակների վրա, եթե դրանք համապատասխանում են որոշակի պահանջներին: Օրինակ, սյունակի արժեքը ստանալու համար օգտագործվող արտահայտությունները պետք է լինեն դետերմինիստական ​​(միշտ վերադարձնել նույն արդյունքը տվյալ մուտքային պարամետրերի համար):
Տվյալների բազայի հարցումներ
Մեկ այլ նկատառում ինդեքսների նախագծման ժամանակ այն է, թե ինչ հարցումներ են կատարվում տվյալների բազայի վրա: Ինչպես նշվեց ավելի վաղ, դուք պետք է հաշվի առնեք, թե որքան հաճախ են փոխվում տվյալները: Բացի այդ, պետք է օգտագործվեն հետևյալ սկզբունքները.
  • Փորձեք տեղադրել կամ փոփոխել որքան հնարավոր է շատ տողեր մեկ հարցման մեջ, այլ ոչ թե դա անել մի քանի առանձին հարցումներում:
  • Ստեղծեք ոչ կլաստերային ինդեքս սյունակների վրա, որոնք հաճախ օգտագործվում են որպես որոնման տերմիններ ձեր հարցումներում: ՈՐՏԵՂև միացումներ ՄԻԱՑԵՔ.
  • Հաշվի առեք ինդեքսավորման սյունակները, որոնք օգտագործվում են տողերի որոնման հարցումներում ճշգրիտ արժեքների համընկնումների համար:

Իսկ հիմա իրականում.

14 հարց SQL Server-ի ինդեքսների մասին, որոնք դուք ամաչում էիք տալ

Ինչու՞ աղյուսակը չի կարող ունենալ երկու կլաստերային ինդեքս:

Ցանկանու՞մ եք կարճ պատասխան: Կլաստերային ինդեքսը աղյուսակ է: Երբ աղյուսակի վրա ստեղծում եք կլաստերային ինդեքս, պահեստավորման շարժիչը դասավորում է աղյուսակի բոլոր տողերը աճման կամ նվազման կարգով՝ ըստ ինդեքսի սահմանման: Կլաստերային ինդեքսը առանձին միավոր չէ, ինչպես մյուս ինդեքսները, այլ աղյուսակում տվյալները տեսակավորելու և տվյալների տողերի արագ մուտքը հեշտացնելու մեխանիզմ:
Պատկերացնենք, որ դուք ունեք վաճառքի գործարքների պատմություն պարունակող աղյուսակ։ Վաճառքի աղյուսակը ներառում է այնպիսի տեղեկություններ, ինչպիսիք են պատվերի ID-ն, ապրանքի դիրքը պատվերի մեջ, ապրանքի համարը, ապրանքի քանակը, պատվերի համարը և ամսաթիվը և այլն: Դուք ստեղծում եք կլաստերային ինդեքս սյունակների վրա Պատվերի IDԵվ LineID, դասավորված է աճման կարգով, ինչպես ցույց է տրված ստորև T-SQLկոդը:
ՍՏԵՂԾԵԼ ԵՆՔԱԿԱՆ ԿԼԱՍՏԵՐ ԻԴԵՔՍ ix_oriderid_lineid ON dbo.Sales(OrderID, LineID);
Երբ գործարկում եք այս սկրիպտը, աղյուսակի բոլոր տողերը ֆիզիկապես կդասակարգվեն սկզբում OrderID սյունակով, այնուհետև՝ ըստ LineID-ի, բայց տվյալներն ինքնին կմնան մեկ տրամաբանական բլոկում՝ աղյուսակում: Այս պատճառով դուք չեք կարող ստեղծել երկու կլաստերային ինդեքս: Կարող է լինել միայն մեկ աղյուսակ մեկ տվյալների հետ, և այդ աղյուսակը կարող է տեսակավորվել միայն մեկ անգամ՝ որոշակի հերթականությամբ:

Եթե ​​կլաստերային աղյուսակը տալիս է բազմաթիվ առավելություններ, ապա ինչո՞ւ օգտագործել կույտ:

Դու ճիշտ ես. Կլաստերային աղյուսակները հիանալի են, և ձեր հարցումների մեծ մասը ավելի լավ կաշխատի այն աղյուսակներում, որոնք ունեն կլաստերային ինդեքս: Բայց որոշ դեպքերում դուք կարող եք ցանկանալ թողնել սեղաններն իրենց բնական, անաղարտ վիճակում, այսինքն. կույտի տեսքով և ստեղծեք միայն ոչ կլաստերային ինդեքսներ՝ ձեր հարցումները շարունակելու համար:
Կույտը, ինչպես հիշում եք, պահում է տվյալները պատահական կարգով: Սովորաբար պահեստավորման ենթահամակարգը տվյալներ է ավելացնում աղյուսակին այն հաջորդականությամբ, որով դրանք տեղադրվում են, բայց պահեստավորման ենթահամակարգը նույնպես սիրում է տողեր տեղափոխել ավելի արդյունավետ պահպանման համար: Արդյունքում, դուք հնարավորություն չունեք գուշակելու, թե ինչ հերթականությամբ կպահվեն տվյալները։
Եթե ​​հարցումների շարժիչը պետք է տվյալներ գտնի առանց ոչ կլաստերային ինդեքսի առավելությունների, ապա այն կկատարի աղյուսակի ամբողջական սկանավորում՝ իրեն անհրաժեշտ տողերը գտնելու համար: Շատ փոքր սեղանների վրա դա սովորաբար խնդիր չէ, բայց քանի որ կույտը մեծանում է չափերով, արդյունավետությունը արագ նվազում է: Իհարկե, ոչ կլաստերային ինդեքսը կարող է օգնել՝ օգտագործելով ցուցիչը դեպի ֆայլը, էջը և տողը, որտեղ պահվում են պահանջվող տվյալները. սա սովորաբար շատ ավելի լավ այլընտրանք է աղյուսակի սկանավորմանը: Չնայած դրան, դժվար է համեմատել կլաստերային ինդեքսի առավելությունները՝ դիտարկելիս հարցումների կատարումը:
Այնուամենայնիվ, կույտը կարող է օգնել բարելավել աշխատանքը որոշակի իրավիճակներում: Դիտարկենք աղյուսակը, որտեղ կան բազմաթիվ ներդիրներ, բայց քիչ թարմացումներ կամ ջնջումներ: Օրինակ, տեղեկամատյան պահող աղյուսակը հիմնականում օգտագործվում է արժեքներ տեղադրելու համար, մինչև այն արխիվացվի: Կույտում դուք չեք տեսնի էջավորումը և տվյալների մասնատումը, ինչպես կտեսնեիք կլաստերային ինդեքսի դեպքում, քանի որ տողերը պարզապես ավելացվում են կույտի վերջում: Էջերի չափից շատ բաժանումը կարող է էական ազդեցություն ունենալ կատարողականի վրա, և ոչ լավ իմաստով: Ընդհանրապես, կույտը թույլ է տալիս համեմատաբար ցավ չպատճառել տվյալները, և դուք ստիպված չեք լինի զբաղվել պահեստավորման և սպասարկման ծախսերի հետ, ինչպես կլաստերային ինդեքսով:
Սակայն տվյալների թարմացման և ջնջման բացակայությունը պետք չէ միակ պատճառը համարել։ Կարևոր գործոն է նաև տվյալների նմուշառման ձևը: Օրինակ, դուք չպետք է օգտագործեք կույտ, եթե դուք հաճախակի հարցումներ եք կատարում տվյալների տիրույթներում, կամ ձեր հարցումների տվյալները հաճախ պետք է տեսակավորվեն կամ խմբավորվեն:
Այս ամենը նշանակում է, որ դուք պետք է հաշվի առնեք կույտի օգտագործումը միայն այն ժամանակ, երբ աշխատում եք շատ փոքր աղյուսակների հետ, կամ աղյուսակի հետ ձեր ամբողջ փոխազդեցությունը սահմանափակվում է տվյալների տեղադրմամբ, և ձեր հարցումները չափազանց պարզ են (և դուք օգտագործում եք ոչ կլաստերային ինդեքսներ: ամեն դեպքում): Հակառակ դեպքում, պահպանեք լավ մշակված կլաստերային ինդեքսը, ինչպիսին է պարզ աճող առանցքային դաշտում սահմանվածը, ինչպես լայնորեն օգտագործվող սյունակը ԻՆՔՆՈՒԹՅՈՒՆ.

Ինչպե՞ս փոխել լռելյայն ինդեքսի լրացման գործակիցը:

Նախնական ինդեքսի լրացման գործակիցը փոխելը մի բան է: Հասկանալը, թե ինչպես է աշխատում լռելյայն հարաբերակցությունը, այլ խնդիր է: Բայց նախ մի քանի քայլ ետ արա: Ինդեքսի լրացման գործակիցը որոշում է էջի տարածքի քանակը՝ ինդեքսը ներքևի մակարդակում (տերևի մակարդակ) պահելու համար՝ նախքան նոր էջ լրացնելը: Օրինակ, եթե գործակիցը դրված է 90, ապա երբ ինդեքսը մեծանա, այն կզբաղեցնի էջի 90%-ը, այնուհետև կտեղափոխվի հաջորդ էջ։
Լռելյայնորեն, ինդեքսի լրացման գործոնի արժեքը նշված է SQL Server 0-ն է, որը նույնն է, ինչ 100-ը: Արդյունքում, բոլոր նոր ինդեքսներն ավտոմատ կերպով ժառանգում են այս պարամետրը, եթե դուք հատուկ չնշեք ձեր կոդի արժեք, որը տարբերվում է համակարգի ստանդարտ արժեքից կամ չփոխեք լռելյայն վարքագիծը: Դուք կարող եք օգտագործել SQL Server Management Studioլռելյայն արժեքը կարգավորելու կամ համակարգում պահվող ընթացակարգը գործարկելու համար sp_configure. Օրինակ՝ հետևյալ հավաքածուն T-SQLհրամանները գործակցի արժեքը սահմանում են 90 (նախ պետք է անցնեք առաջադեմ կարգավորումների ռեժիմին).
EXEC sp_configure «ցուցադրել առաջադեմ տարբերակները», 1; ԳՆԱԼ ՎԵՐԱԿԱՐԳԱՎՈՐՈՒՄ; GO EXEC sp_configure «fill factor», 90; ԳՆԱԼ ՎԵՐԱԿԱՐԳԱՎՈՐՈՒՄ; ԳՆԱՑԵՔ
Ինդեքսի լրացման գործոնի արժեքը փոխելուց հետո դուք պետք է վերագործարկեք ծառայությունը SQL Server. Այժմ կարող եք ստուգել սահմանված արժեքը՝ գործարկելով sp_configure առանց նշված երկրորդ արգումենտի.
EXEC sp_configure «fill factor» GO
Այս հրամանը պետք է վերադարձնի 90 արժեք: Արդյունքում, բոլոր նոր ստեղծված ինդեքսները կօգտագործեն այս արժեքը: Դուք կարող եք դա ստուգել՝ ստեղծելով ինդեքս և հարցում կատարելով լրացման գործոնի արժեքի համար.
ՕԳՏԱԳՈՐԾԵԼ AdventureWorks2012; -- ձեր տվյալների բազան GO CREATE NONCLUSTERED INDEX ix_people_lastname ON Person.Person(LastName); GO SELECT fill_factor FROM sys.indexes WHERE object_id = object_id("Person.Person") AND name="ix_people_lastname";
Այս օրինակում մենք աղյուսակի վրա ստեղծեցինք ոչ կլաստերային ինդեքս Անձտվյալների բազայում AdventureWorks2012. Ինդեքսը ստեղծելուց հետո sys.indexes համակարգի աղյուսակներից կարող ենք ստանալ լրացման գործոնի արժեքը։ Հարցումը պետք է վերադարձնի 90:
Այնուամենայնիվ, եկեք պատկերացնենք, որ մենք ջնջել ենք ինդեքսը և նորից ստեղծել այն, բայց այժմ մենք նշել ենք լրացման գործոնի որոշակի արժեքը.
CREATE NONCLUSTERED INDEX ix_people_lastname ON Person.Person(LastName) WITH (fillfactor=80); GO SELECT fill_factor FROM sys.indexes WHERE object_id = object_id("Person.Person") AND name="ix_people_lastname";
Այս անգամ մենք ավելացրել ենք հրահանգներ ՀԵՏև տարբերակ լրացնող գործոնինդեքսի ստեղծման մեր գործողության համար ՍՏԵՂԾԵԼ ԻԴԵՔՍեւ նշել է արժեքը 80. Օպերատոր ԸՆՏՐԵԼայժմ վերադարձնում է համապատասխան արժեքը:
Մինչ այժմ ամեն ինչ բավականին պարզ է եղել: Այնտեղ, որտեղ դուք իսկապես կարող եք այրվել այս ամբողջ գործընթացում, այն է, երբ դուք ստեղծում եք ինդեքս, որն օգտագործում է լռելյայն գործակցի արժեքը՝ ենթադրելով, որ դուք գիտեք այդ արժեքը: Օրինակ, ինչ-որ մեկը խոժոռում է սերվերի կարգավորումները և այնքան համառ է, որ ինդեքսի լրացման գործակիցը սահմանում է 20: Մինչդեռ դուք շարունակում եք ինդեքսներ ստեղծել՝ ենթադրելով, որ լռելյայն արժեքը 0 է: Ցավոք, դուք ճանապարհ չունեք պարզելու լրացումը: գործակցեք այնքան ժամանակ, քանի դեռ դուք չեք ստեղծում ինդեքս, ապա ստուգեք արժեքը, ինչպես մենք արեցինք մեր օրինակներում: Հակառակ դեպքում, դուք պետք է սպասեք այն պահին, երբ հարցումների կատարողականը այնքան կնվազի, որ դուք սկսեք ինչ-որ բան կասկածել:
Մեկ այլ խնդիր, որը դուք պետք է տեղյակ լինեք, ինդեքսների վերակառուցումն է: Ինչպես ինդեքս ստեղծելու դեպքում, դուք կարող եք նշել ինդեքսի լրացման գործոնի արժեքը, երբ այն վերակառուցեք: Այնուամենայնիվ, ի տարբերություն ստեղծելու ինդեքս հրամանի, վերակառուցումը չի օգտագործում սերվերի լռելյայն կարգավորումները, չնայած այն, ինչ կարող է թվալ: Նույնիսկ ավելին, եթե դուք հատուկ չեք նշում ինդեքսի լրացման գործոնի արժեքը, ապա SQL Serverկօգտագործի այն գործակցի արժեքը, որով այս ցուցանիշը գոյություն ուներ մինչ դրա վերակառուցումը։ Օրինակ՝ հետևյալ գործողությունը ՓՈԽՎԵԼ ԻԴԵՔՍվերակառուցում է մեր նոր ստեղծած ինդեքսը.
ՓՈԽՎԵԼ ԻԴԵՔՍ ix_people_fastname ON Person.Person REBUILD; GO SELECT fill_factor FROM sys.indexes WHERE object_id = object_id("Person.Person") AND name="ix_people_lastname";
Երբ մենք ստուգում ենք լրացման գործոնի արժեքը, մենք կստանանք 80 արժեք, քանի որ դա այն է, ինչ մենք նշել ենք վերջին անգամ ինդեքսը ստեղծելիս: Կանխադրված արժեքը անտեսվում է:
Ինչպես տեսնում եք, ինդեքսի լրացման գործոնի արժեքը փոխելն այնքան էլ դժվար չէ: Շատ ավելի դժվար է իմանալ ընթացիկ արժեքը և հասկանալ, թե երբ է այն կիրառվում: Եթե ​​ինդեքսներ ստեղծելիս և վերակառուցելիս միշտ կոնկրետ նշում եք գործակիցը, ապա միշտ գիտեք կոնկրետ արդյունքը։ Եթե ​​դուք ստիպված չեք լինի անհանգստանալ, որպեսզի համոզվեք, որ ինչ-որ մեկը նորից չի խեղաթյուրում սերվերի կարգավորումները, ինչի հետևանքով բոլոր ինդեքսները վերակառուցվում են ծիծաղելիորեն ցածր ինդեքսների լրացման գործակցով:

Հնարավո՞ր է արդյոք ստեղծել կլաստերային ինդեքս սյունակի վրա, որը պարունակում է կրկնօրինակներ:

Այո եւ ոչ. Այո, դուք կարող եք ստեղծել կլաստերային ինդեքս առանցքային սյունակի վրա, որը պարունակում է կրկնօրինակ արժեքներ: Ոչ, առանցքային սյունակի արժեքը չի կարող մնալ ոչ եզակի վիճակում: Թույլ տուր բացատրեմ. Եթե ​​դուք ստեղծում եք ոչ եզակի կլաստերային ինդեքս սյունակի վրա, պահեստավորման շարժիչը կրկնօրինակ արժեքին միավորիչ է ավելացնում, որպեսզի ապահովի եզակիությունը և, հետևաբար, կարողանա նույնականացնել կլաստերային աղյուսակի յուրաքանչյուր տողը:
Օրինակ, դուք կարող եք որոշել ստեղծել կլաստերային ինդեքս հաճախորդների տվյալներ պարունակող սյունակի վրա Ազգանունպահպանելով ազգանունը. Սյունակը պարունակում է Ֆրանկլին, Հենքոք, Վաշինգտոն և Սմիթ արժեքները: Այնուհետև կրկին տեղադրում եք Ադամս, Հենքոք, Սմիթ և Սմիթ արժեքները: Բայց հիմնական սյունակի արժեքը պետք է եզակի լինի, ուստի պահեստավորման շարժիչը կփոխի կրկնօրինակների արժեքը, որպեսզի նրանք նման լինեն՝ Ադամս, Ֆրանկլին, Հենքոկ, Հանկոկ1234, Վաշինգտոն, Սմիթ, Սմիթ4567 և Սմիթ5678:
Առաջին հայացքից այս մոտեցումը լավ է թվում, բայց ամբողջ թիվը մեծացնում է բանալու չափը, ինչը կարող է խնդիր դառնալ, եթե կան մեծ թվով կրկնօրինակներ, և այդ արժեքները կդառնան ոչ կլաստերային ինդեքսի կամ օտարերկրյա ինդեքսի հիմքը: հիմնական հղում. Այս պատճառներով դուք միշտ պետք է փորձեք ստեղծել եզակի կլաստերային ինդեքսներ, երբ դա հնարավոր է: Եթե ​​դա հնարավոր չէ, ապա գոնե փորձեք օգտագործել շատ բարձր եզակի արժեք ունեցող սյունակներ:

Ինչպե՞ս է աղյուսակը պահվում, եթե խմբավորված ինդեքս չի ստեղծվել:

SQL Serverաջակցում է երկու տեսակի աղյուսակներ՝ կլաստերային աղյուսակներ, որոնք ունեն կլաստերային ինդեքս և կույտային աղյուսակներ կամ պարզապես կույտեր: Ի տարբերություն կլաստերային աղյուսակների, կույտի տվյալները ոչ մի կերպ չեն դասավորված: Ըստ էության, սա տվյալների կույտ է (կույտ): Եթե ​​դուք տող ավելացնեք նման աղյուսակում, ապա պահեստային շարժիչը պարզապես կավելացնի այն էջի վերջում: Երբ էջը լցվի տվյալներով, այն կավելացվի նոր էջ: Շատ դեպքերում, դուք կցանկանաք ստեղծել կլաստերային ինդեքս սեղանի վրա, որպեսզի օգտվեք տեսակավորման և հարցումների արագությունից (փորձեք պատկերացնել, որ հեռախոսահամարը փնտրեք չտեսակավորված հասցեագրքում): Այնուամենայնիվ, եթե որոշեք չստեղծել կլաստերային ինդեքս, դուք դեռ կարող եք ստեղծել ոչ կլաստերային ինդեքս կույտի վրա: Այս դեպքում յուրաքանչյուր ինդեքսային տող կունենա ցուցիչ դեպի կույտ տող: Ցուցանիշը ներառում է ֆայլի ID-ն, էջի համարը և տվյալների գծի համարը:

Ի՞նչ կապ կա արժեքի եզակիության սահմանափակումների և աղյուսակի ինդեքսների հետ առաջնային բանալիի միջև:

Առաջնային բանալին և եզակի սահմանափակումը ապահովում են, որ սյունակի արժեքները եզակի են: Աղյուսակի համար կարող եք ստեղծել միայն մեկ հիմնական բանալի, և այն չի կարող արժեքներ պարունակել ԴԱՏԱՐԿ. Դուք կարող եք ստեղծել մի քանի սահմանափակումներ աղյուսակի համար արժեքի եզակիության վերաբերյալ, և դրանցից յուրաքանչյուրը կարող է ունենալ մեկ գրառում ԴԱՏԱՐԿ.
Երբ դուք ստեղծում եք առաջնային բանալի, պահեստավորման շարժիչը նաև ստեղծում է եզակի կլաստերային ինդեքս, եթե խմբավորված ինդեքսն արդեն չի ստեղծվել: Այնուամենայնիվ, դուք կարող եք անտեսել լռելյայն վարքագիծը և կստեղծվի ոչ կլաստերային ինդեքս: Եթե ​​առաջնային բանալին ստեղծելիս գոյություն ունի կլաստերային ինդեքս, կստեղծվի եզակի ոչ կլաստերային ինդեքս:
Երբ դուք ստեղծում եք եզակի սահմանափակում, պահեստավորման շարժիչը ստեղծում է եզակի, ոչ կլաստերային ինդեքս: Այնուամենայնիվ, դուք կարող եք նշել եզակի կլաստերային ինդեքսի ստեղծումը, եթե նախկինում չի ստեղծվել:
Ընդհանուր առմամբ, եզակի արժեքի սահմանափակումը և եզակի ինդեքսը նույն բանն են:

Ինչու են կլաստերային և ոչ կլաստերային ինդեքսները SQL Server-ում կոչվում B-tree:

SQL Server-ի հիմնական ինդեքսները՝ կլաստերային կամ ոչ կլաստերային, բաշխվում են էջերի խմբերի վրա, որոնք կոչվում են ինդեքսային հանգույցներ: Այս էջերը կազմակերպված են որոշակի հիերարխիայում՝ ծառի կառուցվածքով, որը կոչվում է հավասարակշռված ծառ: Վերին մակարդակում արմատային հանգույցն է, ներքևում՝ տերևային հանգույցները, վերին և ստորին մակարդակների միջև միջանկյալ հանգույցներով, ինչպես ցույց է տրված նկարում.


Արմատային հանգույցը ապահովում է հիմնական մուտքի կետը հարցումների համար, որոնք փորձում են տվյալներ ստանալ ինդեքսի միջոցով: Այս հանգույցից սկսած հարցման շարժիչը սկսում է նավարկություն հիերարխիկ կառուցվածքով դեպի տվյալներ պարունակող համապատասխան տերևային հանգույց:
Օրինակ, պատկերացրեք, որ ստացվել է 82 հիմնական արժեք պարունակող տողեր ընտրելու հարցում: Հարցման ենթահամակարգը սկսում է աշխատել արմատային հանգույցից, որը վերաբերում է համապատասխան միջանկյալ հանգույցին, մեր դեպքում՝ 1-100: 1-100 միջանկյալ հանգույցից անցում է կատարվում 51-100 հանգույցին, իսկ այնտեղից՝ վերջնական 76-100 հանգույցին։ Եթե ​​սա կլաստերային ինդեքս է, ապա հանգույցի տերևը պարունակում է 82-ի բանալու հետ կապված տողի տվյալները: Եթե սա ոչ կլաստերային ինդեքս է, ապա ցուցիչի թերթիկը պարունակում է ցուցիչ դեպի խմբավորված աղյուսակ կամ որոշակի տող: կույտը.

Ինչպե՞ս կարող է ինդեքսը նույնիսկ բարելավել հարցումների կատարումը, եթե դուք պետք է անցնեք այս բոլոր ինդեքսային հանգույցները:

Նախ, ինդեքսները միշտ չէ, որ բարելավում են կատարողականը: Չափից շատ սխալ ստեղծված ինդեքսները համակարգը վերածում են ճահիճի և նվազեցնում հարցումների կատարողականը: Ավելի ճիշտ է ասել, որ եթե ինդեքսները մանրակրկիտ կիրառվեն, դրանք կարող են զգալի արդյունավետություն ապահովել:
Մտածեք մի հսկայական գրքի մասին, որը նվիրված է կատարման թյունինգին SQL Server(թղթային տարբերակ, ոչ էլեկտրոնային տարբերակ): Պատկերացրեք, որ ցանկանում եք տեղեկատվություն գտնել Resource Governor-ի կազմաձևման մասին: Դուք կարող եք ձեր մատը էջ առ էջ քաշել ամբողջ գրքի միջով կամ բացել բովանդակության աղյուսակը և պարզել ճշգրիտ էջի համարը ձեր փնտրած տեղեկություններով (պայմանով, որ գիրքը ճիշտ ինդեքսավորված է, և բովանդակությունը ունի ճիշտ ինդեքսներ): Սա, անշուշտ, կխնայի ձեզ զգալի ժամանակ, թեև նախ պետք է մուտք գործեք բոլորովին այլ կառուցվածք (ինդեքս), որպեսզի ստանաք ձեզ անհրաժեշտ տեղեկատվությունը հիմնական կառուցվածքից (գրքից):
Գրքի ցուցիչի պես՝ ինդեքսը SQL Serverթույլ է տալիս ճշգրիտ հարցումներ կատարել ձեզ անհրաժեշտ տվյալների վրա՝ աղյուսակում պարունակվող բոլոր տվյալները ամբողջությամբ սկանավորելու փոխարեն: Փոքր աղյուսակների դեպքում ամբողջական սկանավորումը սովորաբար խնդիր չէ, բայց մեծ աղյուսակները շատ էջեր են վերցնում տվյալների վրա, ինչը կարող է հանգեցնել հարցումների կատարման նշանակալի ժամանակի, եթե չկա ինդեքս, որը թույլ կտա հարցումների շարժիչին անմիջապես ստանալ տվյալների ճիշտ գտնվելու վայրը: Պատկերացրեք, թե ինչպես եք մոլորվում բազմաստիճան ճանապարհային հանգույցում՝ առանց քարտեզի խոշոր մետրոպոլիայի դիմաց, և դուք կհասկանաք գաղափարը:

Եթե ​​ինդեքսներն այդքան մեծ են, ինչո՞ւ պարզապես չստեղծել մեկը յուրաքանչյուր սյունակում:

Ոչ մի լավ գործ չպետք է անպատիժ մնա. Գոնե ինդեքսների դեպքում այդպես է։ Իհարկե, ինդեքսները հիանալի են աշխատում, քանի դեռ դուք գործարկում եք օպերատորի բեռնման հարցումներ ԸՆՏՐԵԼ, բայց հենց որ սկսվեն հաճախակի զանգերը օպերատորներին ՆԵՐԴՐԵԼ, ԹԱՐՄԱՑՆԵԼԵվ ՋՆՋԵԼ, ուստի լանդշաֆտը շատ արագ փոխվում է։
Երբ օպերատորի կողմից տվյալների հարցում եք նախաձեռնում ԸՆՏՐԵԼ, հարցումների շարժիչը գտնում է ինդեքսը, շարժվում է իր ծառի կառուցվածքով և հայտնաբերում այն ​​տվյալները, որոնք փնտրում են։ Ինչ կարող է լինել ավելի պարզ: Բայց ամեն ինչ փոխվում է, եթե դուք նախաձեռնում եք փոփոխության նման հայտարարություն ԹԱՐՄԱՑՆԵԼ. Այո, հայտարարության առաջին մասի համար հարցումների շարժիչը կարող է կրկին օգտագործել ինդեքսը՝ փոփոխվող տողը գտնելու համար. դա լավ նորություն է: Եվ եթե անընդմեջ տվյալների մեջ պարզ փոփոխություն լինի, որը չի ազդի հիմնական սյունակների փոփոխությունների վրա, ապա փոփոխության գործընթացը լիովին ցավազուրկ կլինի: Բայց ի՞նչ, եթե փոփոխությունը պատճառ դառնա, որ տվյալներ պարունակող էջերը բաժանվեն, կամ առանցքային սյունակի արժեքը փոխվի՝ պատճառելով այն տեղափոխել մեկ այլ ինդեքսային հանգույց, դա կհանգեցնի նրան, որ ինդեքսը, հնարավոր է, կարիք կունենա վերակազմակերպման, որը կազդի բոլոր հարակից ինդեքսների և գործողությունների վրա: , ինչը հանգեցնում է արտադրողականության համատարած անկմանը։
Նմանատիպ գործընթացներ տեղի են ունենում օպերատորին զանգահարելիս ՋՆՋԵԼ. Ինդեքսը կարող է օգնել գտնել ջնջվող տվյալները, սակայն տվյալների ջնջումն ինքնին կարող է հանգեցնել էջի վերափոխման: Օպերատորի վերաբերյալ ՆԵՐԴՐԵԼ, բոլոր ինդեքսների գլխավոր թշնամին. սկսում ես մեծ քանակությամբ տվյալներ ավելացնել, ինչը հանգեցնում է ինդեքսների փոփոխության և դրանց վերակազմավորման և տուժում են բոլորը։
Այսպիսով, հաշվի առեք ձեր տվյալների բազայի հարցումների տեսակները, երբ մտածում եք, թե ինչ տեսակի ինդեքսներ և քանիսը ստեղծել: Ավելի շատ չի նշանակում ավելի լավ: Նախքան աղյուսակում նոր ինդեքս ավելացնելը, հաշվի առեք ոչ միայն հիմնական հարցումների արժեքը, այլև սպառված սկավառակի տարածքը, ֆունկցիոնալության պահպանման արժեքը և ինդեքսները, որոնք կարող են հանգեցնել դոմինոյի էֆեկտի այլ գործողությունների վրա: Ձեր ինդեքսի նախագծման ռազմավարությունը ձեր իրականացման ամենակարևոր ասպեկտներից մեկն է և պետք է ներառի բազմաթիվ նկատառումներ՝ սկսած ինդեքսի չափից, եզակի արժեքների քանակից մինչև ինդեքսի կողմից աջակցվող հարցումների տեսակը:

Արդյո՞ք անհրաժեշտ է առաջնային բանալիով սյունակի վրա ստեղծել կլաստերային ինդեքս:

Դուք կարող եք ստեղծել կլաստերային ինդեքս ցանկացած սյունակի վրա, որը համապատասխանում է պահանջվող պայմաններին: Ճիշտ է, որ կլաստերային ինդեքսը և հիմնական բանալի սահմանափակումը ստեղծված են միմյանց համար և համընկնում են դրախտում, այնպես որ հասկացեք այն փաստը, որ երբ դուք ստեղծում եք հիմնական բանալի, ապա կլաստերային ինդեքսը ավտոմատ կերպով կստեղծվի, եթե այդպիսին չի եղել: ստեղծված նախկինում։ Այնուամենայնիվ, դուք կարող եք որոշել, որ կլաստերային ինդեքսը այլ տեղ ավելի լավ կաշխատի, և հաճախ ձեր որոշումը արդարացված կլինի:
Կլաստերային ինդեքսի հիմնական նպատակն է դասավորել ձեր աղյուսակի բոլոր տողերը՝ հիմնվելով ինդեքսը սահմանելիս նշված հիմնական սյունակի վրա: Սա ապահովում է արագ որոնում և հեշտ մուտք դեպի աղյուսակի տվյալները:
Աղյուսակի առաջնային բանալին կարող է լավ ընտրություն լինել, քանի որ այն եզակի կերպով նույնացնում է աղյուսակների յուրաքանչյուր տող՝ առանց լրացուցիչ տվյալներ ավելացնելու: Որոշ դեպքերում լավագույն ընտրությունը կլինի փոխարինող առաջնային բանալին, որը ոչ միայն եզակի է, այլև փոքր չափսերով, և որի արժեքները հաջորդաբար աճում են՝ ավելի արդյունավետ դարձնելով այս արժեքի վրա հիմնված ոչ կլաստերային ինդեքսները: Հարցման օպտիմիզատորին դուր է գալիս նաև կլաստերացված ինդեքսի և առաջնային բանալու այս համադրությունը, քանի որ աղյուսակների միացումն ավելի արագ է, քան այլ եղանակով միանալը, որը չի օգտագործում հիմնական բանալի և դրա հետ կապված կլաստերային ինդեքսը: Ինչպես ասացի, դա դրախտում ստեղծված խաղ է:
Վերջապես, այնուամենայնիվ, հարկ է նշել, որ կլաստերային ինդեքս ստեղծելիս պետք է հաշվի առնել մի քանի ասպեկտ՝ քանի ոչ կլաստերային ինդեքսներ կհիմնվեն դրա վրա, որքան հաճախ կփոխվի հիմնական ինդեքսի սյունակի արժեքը և որքան մեծ: Երբ կլաստերային ինդեքսի սյունակներում արժեքները փոխվում են կամ ինդեքսը չի գործում այնպես, ինչպես սպասվում էր, ապա սեղանի մյուս բոլոր ինդեքսները կարող են ազդել: Կլաստերային ինդեքսը պետք է հիմնված լինի ամենակայուն սյունակի վրա, որի արժեքներն աճում են որոշակի կարգով, բայց պատահական չեն փոխվում: Ցուցանիշը պետք է աջակցի աղյուսակի ամենահաճախ հասանելի տվյալներին համապատասխան հարցումներին, ուստի հարցումները լիովին օգտվում են այն փաստից, որ տվյալները դասավորված են և հասանելի են արմատային հանգույցներում՝ ինդեքսի տերևներում: Եթե ​​առաջնային բանալին համապատասխանում է այս սցենարին, ապա օգտագործեք այն: Եթե ​​ոչ, ապա ընտրեք սյունակների այլ հավաքածու:

Իսկ եթե դուք ինդեքսավորեք դիտումը, դա դեռ դիտո՞ւմ է:

View-ը վիրտուալ աղյուսակ է, որը ստեղծում է տվյալներ մեկ կամ մի քանի աղյուսակներից: Ըստ էության, դա անվանված հարցում է, որը տվյալներ է առբերում հիմքում ընկած աղյուսակներից, երբ հարցում եք անում այդ տեսակետին: Դուք կարող եք բարելավել հարցումների կատարումը՝ ստեղծելով կլաստերային ինդեքս և ոչ կլաստերային ինդեքսներ այս տեսքի վրա, ինչպես աղյուսակի վրա ինդեքսներ եք ստեղծում, բայց հիմնական նախազգուշացումն այն է, որ նախ ստեղծեք կլաստերային ինդեքս, այնուհետև կարող եք ստեղծել ոչ կլաստերային:
Երբ ստեղծվում է ինդեքսավորված տեսք (նյութականացված տեսք), ապա դիտման սահմանումն ինքնին մնում է առանձին կազմություն: Սա, ի վերջո, պարզապես կոշտ կոդավորված օպերատոր է ԸՆՏՐԵԼ, պահվում է տվյալների բազայում։ Բայց ցուցանիշը բոլորովին այլ պատմություն է։ Երբ մատակարարի վրա ստեղծում եք կլաստերային կամ ոչ կլաստերային ինդեքս, տվյալները ֆիզիկապես պահվում են սկավառակի վրա, ինչպես սովորական ինդեքսը: Բացի այդ, երբ տվյալների հիմքում ընկած աղյուսակներում փոխվում են, դիտումների ինդեքսն ինքնաբերաբար փոխվում է (սա նշանակում է, որ դուք կարող եք խուսափել հաճախակի փոփոխվող աղյուսակների դիտումների ինդեքսավորումից): Ամեն դեպքում, տեսքը մնում է դիտում՝ աղյուսակների տեսք, բայց այս պահին կատարված՝ դրան համապատասխան ինդեքսներով։
Նախքան դիտման վրա ինդեքս ստեղծելը, այն պետք է համապատասխանի մի քանի սահմանափակումների: Օրինակ, դիտումը կարող է հղում կատարել միայն բազային աղյուսակներին, բայց ոչ այլ դիտումների, և այդ աղյուսակները պետք է լինեն նույն տվյալների բազայում: Իրականում կան բազմաթիվ այլ սահմանափակումներ, այնպես որ համոզվեք, որ ստուգեք փաստաթղթերը SQL Serverբոլոր կեղտոտ մանրամասների համար:

Ինչու՞ օգտագործել ծածկույթի ինդեքսը կոմպոզիտային ինդեքսի փոխարեն:

Նախ, եկեք համոզվենք, որ մենք հասկանում ենք երկուսի միջև եղած տարբերությունը: Բաղադրյալ ինդեքսը պարզապես կանոնավոր ինդեքս է, որը պարունակում է մեկից ավելի սյունակ: Բանալինների բազմաթիվ սյունակներ կարող են օգտագործվել՝ համոզվելու համար, որ աղյուսակի յուրաքանչյուր տողը եզակի է, կամ դուք կարող եք ունենալ մի քանի սյունակ՝ համոզվելու համար, որ հիմնական բանալին եզակի է, կամ կարող եք փորձել օպտիմալացնել հաճախակի կանչվող հարցումների կատարումը բազմաթիվ սյունակներում: Ընդհանուր առմամբ, այնուամենայնիվ, որքան շատ հիմնական սյունակներ պարունակի ինդեքսը, այնքան ավելի քիչ արդյունավետ կլինի ինդեքսը, ինչը նշանակում է, որ կոմպոզիտային ինդեքսները պետք է խելամիտ օգտագործվեն:
Ինչպես նշվեց, հարցումը կարող է մեծ օգուտ քաղել, եթե բոլոր պահանջվող տվյալները անմիջապես տեղակայվեն ինդեքսի տերևների վրա, ինչպես ինքնին ինդեքսը: Դա խնդիր չէ կլաստերային ինդեքսի համար, քանի որ բոլոր տվյալները արդեն կան (այդ իսկ պատճառով շատ կարևոր է ուշադիր մտածել կլաստերային ինդեքս ստեղծելիս): Բայց տերևների վրա ոչ կլաստերացված ինդեքսը պարունակում է միայն հիմնական սյունակներ: Մնացած բոլոր տվյալներին մուտք գործելու համար հարցումների օպտիմիզատորը պահանջում է լրացուցիչ քայլեր, որոնք կարող են զգալի ծախսեր ավելացնել ձեր հարցումների կատարմանը:
Այստեղ է, որ օգնության է հասնում ծածկույթի ինդեքսը: Երբ դուք սահմանում եք ոչ կլաստերային ինդեքս, կարող եք նշել լրացուցիչ սյունակներ ձեր հիմնական սյունակների համար: Օրինակ, ենթադրենք, որ ձեր հավելվածը հաճախ է հարցումներ անում սյունակի տվյալների վրա Պատվերի IDԵվ Պատվերի ամսաթիվըաղյուսակում Վաճառք:
SELECT OrderID, OrderDate FROM Sales WHERE OrderID = 12345;
Դուք կարող եք ստեղծել բարդ ոչ կլաստերային ինդեքս երկու սյունակներում, սակայն OrderDate սյունակը կավելացնի միայն ինդեքսի պահպանման ծախսերը՝ առանց ծառայելու որպես հատկապես օգտակար հիմնական սյունակ: Լավագույն լուծումը կլինի առանցքային սյունակի վրա ծածկող ինդեքս ստեղծելը Պատվերի IDև լրացուցիչ ներառված սյունակ Պատվերի ամսաթիվը:
CREATE NONCLUSTERED INDEX ix_orderid ON dbo.Sales(OrderID) INCLUDE (OrderDate);
Սա խուսափում է ավելորդ սյունակների ինդեքսավորման թերություններից՝ միևնույն ժամանակ պահպանելով հարցումները գործարկելիս տերևներում տվյալների պահպանման առավելությունները: Ներառված սյունակը բանալու մաս չէ, բայց տվյալները պահվում են տերևի հանգույցում՝ ինդեքսի թերթիկում։ Սա կարող է բարելավել հարցումների կատարումը առանց լրացուցիչ ծախսերի: Բացի այդ, ծածկույթի ինդեքսում ներառված սյունակները ենթակա են ավելի քիչ սահմանափակումների, քան ինդեքսի հիմնական սյունակները:

Արդյո՞ք կարևոր է հիմնական սյունակում կրկնօրինակների քանակը:

Երբ դուք ստեղծում եք ինդեքս, դուք պետք է փորձեք նվազեցնել կրկնօրինակների թիվը ձեր հիմնական սյունակներում: Ավելի ճիշտ՝ փորձեք հնարավորինս ցածր պահել կրկնությունների մակարդակը:
Եթե ​​դուք աշխատում եք կոմպոզիտային ինդեքսով, ապա կրկնօրինակումը վերաբերում է բոլոր հիմնական սյունակներին որպես ամբողջություն: Մեկ սյունակը կարող է պարունակել բազմաթիվ կրկնօրինակ արժեքներ, բայց բոլոր ինդեքսի սյունակների միջև պետք է լինի նվազագույն կրկնություն: Օրինակ, դուք ստեղծում եք բարդ ոչ կլաստերային ինդեքս սյունակների վրա ԱնունԵվ Ազգանուն, դուք կարող եք ունենալ շատ John Doe արժեքներ և շատ Doe արժեքներ, բայց ցանկանում եք ունենալ որքան հնարավոր է քիչ John Doe արժեքներ, կամ գերադասելի է ընդամենը մեկ John Doe արժեք:
Հիմնական սյունակի արժեքների եզակիության հարաբերակցությունը կոչվում է ինդեքսի ընտրողականություն: Որքան շատ են եզակի արժեքները, այնքան բարձր է ընտրողականությունը. եզակի ինդեքսն ունի առավելագույն հնարավոր ընտրողականություն: Հարցման շարժիչը իսկապես սիրում է բարձր ընտրողականության արժեքներով սյունակներ, հատկապես, եթե այդ սյունակները ներառված են ձեր ամենահաճախ կատարվող հարցումների WHERE կետերում: Որքան ընտրովի է ցուցանիշը, այնքան ավելի արագ է հարցումների շարժիչը կարող նվազեցնել ստացված տվյալների հավաքածուի չափը: Բացասական կողմն, իհարկե, այն է, որ համեմատաբար քիչ եզակի արժեքներով սյունակները հազվադեպ են ինդեքսավորման լավ թեկնածուներ լինելու:

Հնարավո՞ր է ոչ կլաստերային ինդեքս ստեղծել հիմնական սյունակի տվյալների միայն որոշակի ենթաբազմության վրա:

Լռելյայնորեն, ոչ կլաստերային ինդեքսը պարունակում է մեկ տող աղյուսակի յուրաքանչյուր տողի համար: Իհարկե, նույն բանը կարելի է ասել կլաստերային ինդեքսի մասին՝ ենթադրելով, որ նման ցուցանիշը աղյուսակ է։ Բայց երբ խոսքը վերաբերում է ոչ կլաստերային ինդեքսին, մեկ առ մեկ հարաբերությունը կարևոր հասկացություն է, քանի որ, սկսած տարբերակից. SQL Server 2008, դուք հնարավորություն ունեք ստեղծելու զտվող ինդեքս, որը սահմանափակում է դրանում ներառված տողերը։ Զտված ինդեքսը կարող է բարելավել հարցումների կատարումը, քանի որ... այն չափսերով ավելի փոքր է և պարունակում է զտված, ավելի ճշգրիտ վիճակագրություն, քան բոլոր աղյուսակայինները, ինչը հանգեցնում է կատարման բարելավված պլանների ստեղծմանը: Զտված ինդեքսը նաև պահանջում է ավելի քիչ պահեստային տարածք և պահպանման ավելի ցածր ծախսեր: Ցուցանիշը թարմացվում է միայն այն ժամանակ, երբ փոխվում են ֆիլտրին համապատասխանող տվյալները:
Բացի այդ, ֆիլտրացվող ինդեքսը հեշտ է ստեղծել: Օպերատորում ՍՏԵՂԾԵԼ ԻԴԵՔՍդուք պարզապես պետք է նշեք ՈՐՏԵՂֆիլտրի վիճակը. Օրինակ, դուք կարող եք զտել NULL պարունակող բոլոր տողերը ինդեքսից, ինչպես ցույց է տրված կոդում.
CREATE NONCLUSTERED INDEX ix_trackingnumber ON Sales.SalesOrderDetail(CarrierTrackingNumber) ՈՐՏԵՂ CarrierTrackingNumber-ը NULL ՉԷ;
Մենք, փաստորեն, կարող ենք զտել ցանկացած տվյալ, որը կարևոր չէ կարևոր հարցումներում: Բայց զգույշ եղեք, քանի որ... SQL Serverմի քանի սահմանափակումներ է դնում զտվող ինդեքսների վրա, օրինակ՝ դիտման վրա զտվող ինդեքս ստեղծելու անկարողությունը, այնպես որ ուշադիր կարդացեք փաստաթղթերը:
Հնարավոր է նաև, որ դուք կարող եք նմանատիպ արդյունքների հասնել՝ ստեղծելով ինդեքսավորված տեսք: Այնուամենայնիվ, զտված ինդեքսն ունի մի քանի առավելություններ, ինչպիսիք են սպասարկման ծախսերը նվազեցնելու և ձեր կատարողական ծրագրերի որակը բարելավելու ունակությունը: Զտված ինդեքսները կարող են նաև վերակառուցվել առցանց: Փորձեք սա ինդեքսավորված տեսքով:

Եվ դարձյալ մի քիչ թարգմանչից

Habrahabr-ի էջերում այս թարգմանության հայտնվելու նպատակն էր պատմել կամ հիշեցնել ձեզ SimpleTalk բլոգի մասին. RedGate.
Այն հրապարակում է բազմաթիվ զվարճալի և հետաքրքիր գրառումներ։
Ես կապված չեմ որևէ ընկերության արտադրանքի հետ RedGate, ոչ էլ դրանց վաճառքով։

Ինչպես խոստացել էինք, գրքեր նրանց համար, ովքեր ցանկանում են ավելին իմանալ
Ես խորհուրդ եմ տալիս երեք շատ լավ գիրք ինձանից (հղումները տանում են դեպի վառելտարբերակները խանութում Amazon):

Սկզբունքորեն, դուք կարող եք բացել պարզ ինդեքսներ
  • սկսնակների համար
  • ցուցանիշը
  • Ավելացնել պիտակներ
    Microsoft SQL Server 2012 T-SQL Fundamentals (մշակողի տեղեկանք)
    Հեղինակ Իցիկ Բեն-Գան
    Հրապարակման ամսաթիվ՝ 15 հուլիսի 2012թ
    Հեղինակը, իր գործի վարպետը, տարրական գիտելիքներ է տալիս շտեմարանների հետ աշխատելու մասին։
    Եթե ​​մոռացել եք ամեն ինչ կամ երբեք չեք իմացել, անպայման արժե կարդալ:

    ROWID ինդեքսներտվյալների բազայի օբյեկտներ են, որոնք ապահովում են աղյուսակի սյունակի բոլոր արժեքների ցուցադրումը, ինչպես նաև աղյուսակի բոլոր տողերի ROWID-ները, որոնք պարունակում են սյունակի արժեքները:

    ROWIDկեղծ սյունակ է, որը եզակի նույնացուցիչ է աղյուսակի տողի համար և իրականում նկարագրում է տվյալ տողի ճշգրիտ ֆիզիկական գտնվելու վայրը: Այս տեղեկատվության հիման վրա Oracleկարող է հետագայում գտնել աղյուսակի տողի հետ կապված տվյալները: Ամեն անգամ, երբ տողը տեղափոխվում, արտահանվում, ներմուծվում է կամ որևէ այլ գործողություն, որը փոխում է իր գտնվելու վայրը, ROWIDգիծ, քանի որ այն զբաղեցնում է այլ ֆիզիկական դիրք: Տվյալների պահպանման համար ROWIDՊահանջվում է 80 բիթ (10 բայթ): Նույնացուցիչներ ROWIDբաղկացած է չորս բաղադրիչներից՝ օբյեկտի համարը (32 բիթ), հարաբերական ֆայլի համարը (10 բիթ), բլոկի համարը (22 բիթ) և տողի համարը (16 բիթ): Այս նույնացուցիչները ցուցադրվում են որպես 18 նիշից բաղկացած հաջորդականություն, որը ցույց է տալիս տվյալների բազայի գտնվելու վայրը, ընդ որում յուրաքանչյուր նիշ ներկայացված է base-64 ձևաչափով, որը բաղկացած է A-Z, a-z, 0-9, + և / նիշերից: Առաջին վեց նիշերը տվյալների օբյեկտի համարն են, հաջորդ երեքը` հարաբերական ֆայլի համարը, հաջորդ վեցը` բլոկի համարը, իսկ վերջին երեքը` տողի համարը:

    Օրինակ:

    ԸՆՏՐԵԼ ընտանիք, ROWIDՈւսանողից;

    FAM ROWID

    ——————————————

    ԻՎԱՆՈՎ AAAA3kAAGAAAAGsAAA

    ՊԵՏՐՈՎ AAAA3kAAGAAAAGsAAB

    Տվյալների բազայում Oracleինդեքսներն օգտագործվում են տարբեր նպատակներով՝ տվյալների բազայում արժեքների եզակիությունը ապահովելու, աղյուսակում գրառումների որոնման արդյունավետությունը բարելավելու համար և այլն: Կատարումը բարելավվում է՝ որոնման չափանիշներում ինդեքսավորված սյունակին կամ սյունակներին հղում կատարելով: աղյուսակի տվյալների համար: IN Oracleինդեքսները կարող են ստեղծվել ցանկացած սեղանի սյունակում, բացառությամբ LONG սյունակների: Ինդեքսները տարբերում են արագության նկատմամբ անզգայուն և բարձր արդյունավետությամբ հավելվածները, հատկապես մեծ սեղանների հետ աշխատելիս: Այնուամենայնիվ, նախքան ինդեքս ստեղծելու որոշում կայացնելը, դուք պետք է կշռադատեք համակարգի կատարողականի դրական և բացասական կողմերը: Արդյունավետությունը չի բարելավվի, եթե պարզապես մուտքագրեք ինդեքս և մոռանաք դրա մասին:

    Թեև կատարողականի ամենամեծ բարելավումը գալիս է սյունակի վրա ինդեքս ստեղծելուց, որտեղ բոլոր արժեքները եզակի են, դուք կարող եք նմանատիպ արդյունքներ ստանալ կրկնօրինակ կամ NULL արժեքներ պարունակող սյունակների համար: Ինդեքս ստեղծելու համար պարտադիր չէ, որ սյունակների արժեքները եզակի լինեն: Ահա մի քանի առաջարկներ, որոնք կօգնեն ձեզ հասնել ցանկալի կատարողականի բարձրացման՝ ստանդարտ ինդեքս օգտագործելիս, և մենք նաև կանդրադառնանք կատարողականի և սկավառակի տարածության սպառման միջև հավասարակշռության հետ կապված խնդիրներին՝ ինդեքս ստեղծելիս:

    Աղյուսակներում տեղեկատվություն փնտրելու համար ինդեքսների օգտագործումը կարող է արդյունավետության զգալի բարելավումներ ապահովել սկանավորման աղյուսակների նկատմամբ, որոնց սյունակները ինդեքսավորված չեն: Այնուամենայնիվ, ճիշտ ինդեքս ընտրելն ամենևին էլ հեշտ չէ։ Իհարկե, սյունակը, որի արժեքները բոլորը եզակի են, նախընտրելի է B-tree ինդեքսով ինդեքսավորելու համար, սակայն այն սյունակը, որը չի համապատասխանում այս պահանջներին, լավ թեկնածու է, քանի դեռ նրա տողերի մոտ 10%-ը պարունակում է նույնական արժեքներ: և ոչ ավելին: «Փոխարկիչ» կամ «դրոշակ» սյունակները, օրինակ՝ նրանք, որոնք պահում են տեղեկատվություն անձի սեռի մասին, հարմար չեն B-tree ինդեքսների համար: Սյունակները, որոնք օգտագործվում են փոքր թվով «հուսալի արժեքներ» պահելու համար, ինչպես նաև դրանք, որոնք պահում են: որոշակի արժեքներ նույնպես հարմար չեն: Այնուհետև նշանները, օրինակ՝ «հուսալիություն» կամ «անհուսալիություն», «գործունեություն» կամ «անգործունեություն», «այո» կամ «ոչ» և այլն, և այլն: Վերջապես, հակադարձ ստեղներով ինդեքսներն են. օգտագործվում է, որպես կանոն, որտեղ այն տեղադրված է և գործում OracleԶուգահեռ սերվեր և դուք պետք է առավելագույնի հասցնեք տվյալների բազայի զուգահեռության մակարդակը: