MS sql ინდექსები. Sql სერვერი - აქვს თუ არა მნიშვნელობა შეკვეთას Microsoft SQL-ში დაფარვის ინდექსის შექმნისას? მუდმივი გამოთვლილი სვეტები

--ინდექსი არის სტრუქტურა დისკზე, რომელიც ასოცირდება ცხრილთან ან ხედთან და აჩქარებს რიგების ამოღებას ცხრილიდან ან ხედიდან. ინდექსი შეიცავს კლავიშებს, რომლებიც აგებულია ცხრილის ან ხედის ერთი ან მეტი სვეტიდან. ეს გასაღებები ინახება დაბალანსებულ ხის სტრუქტურაში, რომელიც მხარს უჭერს სტრიქონების სწრაფ ძიებას მათი საკვანძო მნიშვნელობებით SQL Server-ში.

-- კლასტერული ინდექსები ახარისხებენ და ინახავენ მონაცემთა სტრიქონებს ცხრილებში ან ხედებში მათი ძირითადი მნიშვნელობების მიხედვით. ეს მნიშვნელობები არის სვეტები, რომლებიც შედის ინდექსის განმარტებაში. თითო ცხრილზე არის მხოლოდ ერთი კლასტერული ინდექსი, რადგან მონაცემთა რიგების დალაგება შესაძლებელია მხოლოდ ერთი თანმიმდევრობით.
-- ცხრილის მონაცემების რიგები ინახება დალაგების თანმიმდევრობით მხოლოდ იმ შემთხვევაში, თუ ცხრილი შეიცავს კლასტერულ ინდექსს. თუ ცხრილს აქვს კლასტერული ინდექსი, მაშინ ცხრილს კლასტერული ეწოდება. თუ ცხრილს არ აქვს კლასტერული ინდექსი, მონაცემთა სტრიქონები ინახება უწესრიგო სტრუქტურაში, რომელსაც ეწოდება გროვა.

--არაკლასტერულ ინდექსს აქვს ზუსტად იგივე სტრუქტურა, რაც კლასტერულ ინდექსს, მაგრამ ორი მნიშვნელოვანი განსხვავებებით:
--არაკლასტერული ინდექსი არ ცვლის ცხრილის რიგების ფიზიკურ წესრიგს და არაკლასტერული ინდექსის ფოთლის გვერდები შედგება ინდექსის გასაღებებისა და სანიშნეებისგან.

--კლასტერული ინდექსები უზრუნველყოფს მონაცემთა უფრო სწრაფ მოძიებას, ვიდრე არაკლასტერული ინდექსები. ისინი, როგორც წესი, უფრო სწრაფი აღმოჩნდებიან განახლებისას, მაგრამ არა მაშინ, როდესაც ბევრი განახლება ხდება ერთსა და იმავე ადგილას ურთიერთობის შუაგულში.

- რატომღაც, კლასტერული ინდექსი უფრო სწრაფად მუშაობს, ვიდრე არაკლასტერული ინდექსი. როდესაც სისტემა სკანირებს კლასტერულ ინდექსს, არ არის საჭირო B-ხის სტრუქტურის დატოვება მონაცემთა გვერდების სკანირებისთვის, რადგან ასეთი გვერდები უკვე არსებობს ხის ფოთლის დონეზე.

--არაკლასტერული ინდექსი ასევე მოითხოვს უფრო მეტ 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;
DECLARE @t CHAR(1) = "T";

WHILE @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;
ᲓᲐᲡᲐᲡᲠᲣᲚᲘ

--შეკითხვები მაგიდაზე ინდექსებით
აირჩიეთ ID, T FROM tsql.dbo.NCI
შეკვეთა პირადობის მოწმობით, თ

SELECT ID, COUNT(*) AS C FROM tsql.dbo.NCI
ჯგუფი ID-ით, ტ

აირჩიეთ ID, T FROM tsql.dbo.NCI
WHERE ID > 4000 და ID< 55000 AND T LIKE "T%"

--შეკითხვა ორივე ინდექსის გამოყენებით
გამოიყენეთ tsql;
აირჩიეთ CAST(dbo.NCI.ID AS VARCHAR)
dbo.NCI-დან
GROUP BY dbo.NCI.ID
UNION ALL
აირჩიეთ 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, "DETAILED");

-- ინდექსების წაშლა
IF EXISTS (აირჩიეთ სახელი sys.indexes-დან
WHERE სახელი = N"IX_1")
DROP INDEX IX_1 ON tsql.dbo.NCI;

IF EXISTS (აირჩიეთ სახელი sys.indexes-დან
WHERE სახელი = N"IX_2")
DROP INDEX IX_2 ON tsql.dbo.NCI;

წინა სტატიაში ჩვენ წარმოვადგინეთ რელაციური მონაცემთა ბაზების ოპტიმიზაციის გზები და განვიხილეთ, თუ როგორ მუშაობს კლასტერული და არაკლასტერული ინდექსები მონაცემთა ბაზის შეკითხვის შესრულების დროის ოპტიმიზაციის კონტექსტში. ახლა დროა გამოვიყენოთ ეს ცოდნა პრაქტიკაში, ვისწავლოთ როგორ შევქმნათ ოპტიმიზაციის ინდექსები MS SQL მონაცემთა ბაზისთვის.

ნება მომეცით შეგახსენოთ Staffs ცხრილის სქემის განმარტება, რომლითაც ჩვენ ვიმუშავებთ:

პერსონალის მაგიდა

ვთქვათ, ჩვენ უნდა შევქმნათ არაკლასტერული ინდექსი Staffs ცხრილისთვის, რომელიც ოპტიმიზაციას გაუწევს შემდეგ შეკითხვას:

აირჩიეთ პირადობის მოწმობა, სახელი, ვაკანსია პერსონალიდან, სადაც ხელფასი > 1000 და ფოტო არ არის NULL

ინდექსის გასაღები იქნება SELARY და Photo სვეტები, რადგან არჩევანი იფილტრება ამ ველებით. და Id, Name და Job სვეტები იქნება ინდექსში ჩართული სვეტები.

ზოგადი ბრძანების სინტაქსი ასეთია:

გამოყენება წადი

შექმენით არაკლასტერული ინდექსი ჩართულია (ASC -- ინდექსის გასაღების სვეტები)

ჩართვა ( -- ჩართული სვეტები) GO

ჩვენს შემთხვევაში, მოთხოვნა ასე გამოიყურება:

(ხელფასი, ფოტო) მოიცავს (ID, სახელი, ვაკანსია) GO

ჩვენ შევქმენით არაკლასტერული ინდექსი. უფრო სწორად, არაკლასტერული დაფარვის ინდექსი. ეს ნიშნავს, რომ ინდექსი შეიცავს ყველა ველს, რომელიც აუცილებელია მოთხოვნის შესასრულებლად და SQL Server არ მიიღებს წვდომას საბაზისო ცხრილში მოთხოვნის შესრულებისას.

ჩვენი კოდი რომ იყოს ასეთი:

CREATE NONCLUSTERED INDEX IDX_StaffsSearch ON Stuffs

(ხელფასი, ფოტო) მოიცავს (Id) GO

ამ შემთხვევაში, ინდექსი წყვეტს დაფარვის ინდექსს, რადგან ის არ მოიცავს მოთხოვნაში გამოყენებულ ყველა სვეტს. ოპტიმიზატორი კვლავ გამოიყენებს ამ ინდექსს მოთხოვნის შესრულებისას, მაგრამ მისი ეფექტურობა შემცირდება სიდიდის ბრძანებით, რადგან მას დასჭირდება წვდომა საბაზისო ცხრილში.

კლასტერული ინდექსი იქმნება შემდეგი ბრძანების გამოყენებით:

CLUSTERED INDEX IDX_Stsffsid ON პერსონალის შექმნა (Id)

აქ შეიქმნა უნიკალური კლასტერული ინდექსი ცხრილის პირველადი გასაღების (Id სვეტი) საფუძველზე.

რეალური მაგალითი

მოდით ახლა განვავითაროთ სცენარი, რომელშიც ჩვენ შეგვიძლია რეალისტურად შევაფასოთ შესრულების გაზრდის ხარისხი ინდექსების გამოყენების შემთხვევაში.

მოდით შევქმნათ ახალი მონაცემთა ბაზა:

მონაცემთა ბაზის შექმნა TestDB;

და ერთი კლიენტების ცხრილი, რომელიც შედგება ოთხი სვეტისგან:

შექმენით მაგიდა .(

NOT NULL, NULL, NULL, NULL) GO

ახლა მოდით შეავსოთ ჩვენი ცხრილი შემთხვევითი მონაცემებით. Id სვეტი გაიზრდება ციკლში, ხოლო ცხრილის დარჩენილი სამი სვეტი შეივსება შემთხვევითი რიცხვებით შემთხვევითი ფუნქციის თავისებური ვერსიის გამოყენებით:

გამოაცხადე @i int = 0;

Სანამ მე< 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) აირჩიეთ ID, Num1, Num2 კლიენტებისგან WHERE Id = 2000

2) აირჩიეთ ID, Num1, Num2 კლიენტებისგან WHERE Id >= 0 და ID< 1000

3) აირჩიეთ ID, Num1, Num2 კლიენტებისგან WHERE Id >= 0 და ID< 5000

ეს მოთხოვნები დააბრუნებს 1 სტრიქონს, 1000 მწკრივს და 5000 რიგს, შესაბამისად. ინდექსების გარეშე, შესრულების ინდიკატორი (ლოგიკური წაკითხვის რაოდენობა) ყველა მოთხოვნისთვის არის იგივე და ტოლია 1621-ის. მოდით შევიტანოთ მონაცემები შედეგების ცხრილში:

ჩვენ ვხედავთ, რომ მეორე და მესამე შეკითხვებისთვის, როდესაც საკმაოდ დიდი რაოდენობის რიგები დაბრუნდება, ჩვენ მიერ შექმნილმა ინდექსმა არ გააუმჯობესა შესრულება. თუმცა, შეკითხვისთვის, რომელიც აბრუნებს ერთ მწკრივს, სიჩქარე უზარმაზარი იყო. ამგვარად, შეგვიძლია დავასკვნათ, რომ აზრი აქვს არა-დაფარვის ინდექსების შექმნას მოთხოვნების ოპტიმიზაციისას, რომლებიც აბრუნებენ ერთ შედეგს.

ახლა მოდით შევქმნათ დაფარვის ინდექსი, რითაც მივაღწევთ მაქსიმალურ შესრულებას.

პირველ რიგში, მოდით წავშალოთ წინა ინდექსი:

გამოიყენეთ TestDB GO DROP INDEX Customers.TestIndex1

და მოდით შევქმნათ ახალი ინდექსი:

CREATE NONCLUSTERED INDEX TestIndex2 ON dbo.Customers(Id) IncluDE (Num1, Num2);

ახლა მოდით გავუშვათ ჩვენი მოთხოვნები მესამედ და ჩავწეროთ შედეგები ცხრილში:

არ არის ინდექსები

არადაფარვის ინდექსი

დაფარვის ინდექსი

ადვილი მისახვედრია, რომ შესრულების ზრდა უზარმაზარი იყო. ამრიგად, ჩვენ ათჯერ გავზარდეთ შეკითხვის შესრულების სიჩქარე. მონაცემთა ბაზის გაშვებისას, რომელიც ინახავს მილიონობით მწკრივს, შესრულების ეს ზრდა საკმაოდ შესამჩნევი იქნება.

ამ სტატიაში ჩვენ განვიხილეთ მონაცემთა ბაზის ოპტიმიზაციის მაგალითი ინდექსების შექმნით. აღსანიშნავია, რომ ინდექსების შექმნა არის წმინდა ინდივიდუალური პროცესი თითოეული მოთხოვნისთვის. იმისათვის, რომ შექმნათ ინდექსი, რომელიც ნამდვილად გააუმჯობესებს შეკითხვის შესრულებას, თქვენ უნდა ყურადღებით გაანალიზოთ თავად მოთხოვნა და მისი შესრულების გეგმა.

ეფექტური ინდექსის შექმნა არის ერთ-ერთი საუკეთესო გზა მონაცემთა ბაზის აპლიკაციის მუშაობის გასაუმჯობესებლად. ინდექსების გამოყენების გარეშე, SQL Server ჰგავს მკითხველს, რომელიც ცდილობს იპოვოს სიტყვა წიგნში ყოველი გვერდის დათვალიერებით. თუ წიგნს აქვს საგნობრივი ინდექსი (ინდექსი), მკითხველს შეუძლია საჭირო ინფორმაციის მოძიება ბევრად უფრო სწრაფად.

ინდექსის არარსებობის შემთხვევაში, SQL სერვერი, ცხრილიდან მონაცემების მიღებისას, დაასკანირებს მთელ ცხრილს და შეამოწმებს თითოეულ რიგს, რომ ნახოს შეკითხვის კრიტერიუმების დაკმაყოფილება. ასეთი სრული სკანირება შეიძლება დამღუპველი იყოს მთელი სისტემის მუშაობისთვის, განსაკუთრებით იმ შემთხვევაში, თუ ცხრილებში ბევრი მონაცემია.

მონაცემთა ბაზასთან მუშაობისას ერთ-ერთი ყველაზე მნიშვნელოვანი ამოცანაა ოპტიმალური ინდექსის შექმნა სისტემის მუშაობის გასაუმჯობესებლად. ძირითადი მონაცემთა ბაზების უმეტესობა გთავაზობთ ინსტრუმენტებს შეკითხვის შესრულების გეგმის სანახავად და დაგეხმარებათ ინდექსების რეგულირებასა და ოპტიმიზაციაში. ეს სტატია ხაზს უსვამს რამდენიმე კარგ წესს, რომლებიც გამოიყენება მონაცემთა ბაზაში ინდექსების შექმნის ან შეცვლისას. პირველ რიგში, მოდით შევხედოთ სიტუაციებს, როდესაც ინდექსირება აუმჯობესებს შესრულებას და სადაც ინდექსირებამ შეიძლება ზიანი მიაყენოს.

სასარგებლო ინდექსები

ასე რომ, ცხრილის ინდექსირება სასარგებლო იქნება ცხრილში კონკრეტული ჩანაწერის ძებნისას Where განაცხადის გამოყენებით. ასეთი მოთხოვნები მოიცავს, მაგალითად, შეკითხვებს, რომლებიც ეძებენ მნიშვნელობების დიაპაზონს, შეკითხვებს, რომლებიც ემთხვევა ზუსტ მნიშვნელობას კონკრეტულ მნიშვნელობას და შეკითხვებს, რომლებიც აერთიანებს ორ ცხრილს.

მაგალითად, შემდეგი მოთხოვნები Northwind მონაცემთა ბაზის წინააღმდეგ უფრო ეფექტურად იმუშავებს UnitPrice სვეტზე ინდექსის შექმნისას.

წაშლა პროდუქტებიდან, სადაც UnitPrice=1
აირჩიეთ * პროდუქტებიდან, სადაც ერთეულის ფასი 14-დან 16-მდეა

იმის გამო, რომ ინდექსის ელემენტები ინახება დალაგებულად, ინდექსირება ასევე სასარგებლოა შეკითხვის შექმნისას პუნქტის მიხედვით. ინდექსის გარეშე ჩანაწერები იტვირთება და დალაგებულია მოთხოვნის გაშვებისას. UnitPrice-ზე დაფუძნებული ინდექსი საშუალებას მოგცემთ უბრალოდ სკანიროთ ინდექსი და მიიღოთ რიგები მითითებით შემდეგი მოთხოვნის დამუშავებისას. თუ გსურთ დაალაგოთ რიგები კლებადობით, შეგიძლიათ უბრალოდ დაასკანიროთ ინდექსი საპირისპირო თანმიმდევრობით.

აირჩიეთ * პროდუქტებიდან შეკვეთა UnitPrice ASC-ით

ჯგუფის გამოყენებით ჩანაწერის დაჯგუფება განცხადების მიხედვით ასევე ხშირად მოითხოვს დახარისხებას, ამიტომ ინდექსის შექმნა ერთეული ფასის სვეტზე ასევე სასარგებლო იქნება შემდეგი მოთხოვნისთვის, რომელიც ითვლის პროდუქტის ერთეულების რაოდენობას თითოეულ კონკრეტულ ფასზე.

აირჩიეთ რაოდენობა(*), UnitPrice პროდუქტების ჯგუფიდან UnitPrice-ის მიხედვით

ინდექსები სასარგებლოა სვეტისთვის უნიკალური მნიშვნელობის შესანარჩუნებლად, ვინაიდან DBMS ადვილად ხედავს ინდექსს, რომ ნახოს მნიშვნელობა უკვე არსებობს. ამ მიზეზით, პირველადი გასაღებები ყოველთვის ინდექსირებულია.

ინდექსირების ნაკლოვანებები

ინდექსები ამცირებენ სისტემის მუშაობას ჩანაწერის ცვლილებების დროს. ნებისმიერ დროს, როდესაც მოთხოვნა შესრულებულია ცხრილში მონაცემების შესაცვლელად, ინდექსიც უნდა შეიცვალოს. ინდექსების ოპტიმალური რაოდენობის შესარჩევად, თქვენ უნდა შეამოწმოთ მონაცემთა ბაზა და აკონტროლოთ მისი შესრულება. სტატიკური სისტემები, სადაც მონაცემთა ბაზები ძირითადად გამოიყენება მონაცემთა მოსაძიებლად, როგორიცაა მოხსენება, შეიძლება შეიცავდეს მეტ ინდექსს მხოლოდ წაკითხული მოთხოვნების მხარდასაჭერად. მონაცემთა შესაცვლელად დიდი რაოდენობით ტრანზაქციის მქონე მონაცემთა ბაზებს დასჭირდებათ ინდექსების მცირე რაოდენობა უფრო მაღალი გამტარუნარიანობის უზრუნველსაყოფად.

ინდექსები იკავებს დამატებით ადგილს დისკზე და RAM-ში. ზუსტი ზომა დამოკიდებული იქნება ცხრილში ჩანაწერების რაოდენობაზე, ასევე ინდექსში სვეტების რაოდენობასა და ზომაზე. უმეტეს შემთხვევაში, ეს არ არის მთავარი საკითხი, რადგან დისკის სივრცე ახლა ადვილია შესწიროს უკეთესი შესრულებისთვის.

ოპტიმალური ინდექსის აგება

მარტივი ინდექსი

მარტივი ინდექსი არის ინდექსი, რომელიც იყენებს ცხრილის ერთი ველის მნიშვნელობებს. მარტივი ინდექსის გამოყენება სასარგებლოა ორი მიზეზის გამო. პირველ რიგში, მონაცემთა ბაზის გაშვება დიდ სტრესს აყენებს თქვენს მყარ დისკზე. დიდი ინდექსის გასაღებები აიძულებს მონაცემთა ბაზას შეასრულოს მეტი I/O ოპერაციები, რაც ზღუდავს შესრულებას.

მეორე, იმის გამო, რომ ინდექსის ელემენტები ხშირად მონაწილეობენ შედარებაში, უფრო მცირე ინდექსების შედარება უფრო ადვილია. ამ ორი მიზეზის გამო, ერთი მთელი სვეტი უკეთესი ინდექსია, რადგან ის მცირეა და ადვილად შესადარებელი. სიმბოლოთა სტრიქონები, მეორეს მხრივ, მოითხოვს სიმბოლოების შედარებას და ყურადღებას პარამეტრის დამუშავებაზე.

შერჩევითი ინდექსი

ყველაზე ეფექტური ინდექსებია დუბლიკატების დაბალი პროცენტული ინდექსები. მაგალითად, ქალაქის სატელეფონო დირექტორია, სადაც თითქმის ყველას აქვს გვარი სმიტი, არ იქნება ისეთი სასარგებლო, თუ მასში ჩანაწერები დალაგებულია გვარის მიხედვით.

უნიკალური მნიშვნელობების მაღალი პროცენტული ინდექსს ასევე უწოდებენ შერჩევით ინდექსს. ცხადია, უნიკალურ ინდექსს აქვს უდიდესი სელექციურობა, რადგან ის არ შეიცავს დუბლიკატულ მნიშვნელობებს. ბევრ DBMS-ს შეუძლია აკონტროლოს სტატისტიკა თითოეული ინდექსის შესახებ და შეუძლია ამოიცნოს, თუ რამდენ არადუბლიკატულ მნიშვნელობას შეიცავს თითოეული ინდექსი. ეს სტატისტიკა გამოიყენება შეკითხვის შესრულების გეგმის გენერირებისას.

დაფარვის ინდექსები

ინდექსები შედგება მონაცემთა სვეტისგან, რომელზედაც თავად ინდექსია აგებული და შესაბამისი მწკრივის მაჩვენებლისგან. ეს წიგნის ინდექსს ჰგავს: ის უბრალოდ შეიცავს საკვანძო სიტყვებს და ბმულს იმ გვერდისკენ, რომელზეც შეგიძლიათ გადახვიდეთ დამატებითი ინფორმაციისთვის. როგორც წესი, DBMS მიჰყვება მითითებებს ინდექსიდან მწკრივისკენ, რათა შეაგროვოს მოთხოვნისთვის საჭირო ყველა ინფორმაცია. თუმცა, თუ ინდექსი შეიცავს მოთხოვნაში საჭირო ყველა სვეტს, ინფორმაციის მოძიება შესაძლებელია თავად ცხრილზე წვდომის გარეშე.

მოდით განვიხილოთ ინდექსი UnitPrice სვეტზე, რომელიც უკვე აღინიშნა ზემოთ. DBMS-ს შეუძლია გამოიყენოს მხოლოდ ინდექსის ელემენტები შემდეგი მოთხოვნის შესასრულებლად.

აირჩიეთ Count(*), UnitPrice პროდუქტების ჯგუფიდან UnitPrice-ის მიხედვით

ამ ტიპის შეკითხვას ეწოდება დაფარვის შეკითხვა, რადგან მოთხოვნილი ყველა სვეტი შეიძლება იყოს მოძიებული ერთი ინდექსიდან. ყველაზე მნიშვნელოვანი კითხვებისთვის, შეიძლება განიხილოთ დაფარვის ინდექსის შექმნა საუკეთესო შესაძლო შესრულებისთვის. ასეთი ინდექსები სავარაუდოდ კომპოზიციური იქნება (ერთზე მეტი სვეტის გამოყენებით), რაც პირველი პრინციპის საპირისპიროა: მარტივი ინდექსების შექმნა. ცხადია, ინდექსში სვეტების ოპტიმალური რაოდენობის არჩევა შეიძლება შეფასდეს მხოლოდ სხვადასხვა სიტუაციებში მონაცემთა ბაზის მუშაობის ტესტირებისა და მონიტორინგის გზით.

კლასტერული ინდექსი

ბევრ მონაცემთა ბაზას აქვს ერთი სპეციალური ინდექსი მაგიდაზე, სადაც მწკრივის ყველა მონაცემი შეიცავს ინდექსში. SQL Server-ში ასეთ ინდექსს კლასტერული ინდექსი ეწოდება. კლასტერული ინდექსი შეიძლება შევადაროთ სატელეფონო დირექტორიას, რადგან ინდექსის თითოეული ელემენტი შეიცავს ყველა საჭირო ინფორმაციას და არ შეიცავს ბმულებს დამატებითი მონაცემების მისაღებად.

არსებობს ზოგადი წესი - ყველა არატრივიალურ ცხრილს უნდა ჰქონდეს კლასტერული ინდექსი. თუ შესაძლებელია მაგიდაზე მხოლოდ ერთი ინდექსის შექმნა, გააკეთეთ იგი კლასტერულად. SQL Server-ში პირველადი გასაღების შექმნისას ავტომატურად შეიქმნება კლასტერული ინდექსი (თუ ის უკვე არ შეიცავს), ინდექსირების გასაღებად პირველადი გასაღების სვეტის გამოყენებით. კლასტერული ინდექსი არის ყველაზე ეფექტური ინდექსი (თუ გამოიყენება, ის მოიცავს მთელ შეკითხვას) და ბევრ DBMS-ში ასეთი ინდექსი ეხმარება ეფექტურად მართოს ცხრილების შესანახად მოთხოვნილი სივრცე, რადგან სხვაგვარად (კლასტერული ინდექსის შექმნის გარეშე) ცხრილის რიგები ინახება მოუწესრიგებელი სტრუქტურა, რომელსაც გროვა უწოდა.

ფრთხილად იყავით კლასტერული ინდექსისთვის სვეტების არჩევისას. თუ თქვენ შეცვლით ჩანაწერს და შეცვლით სვეტის მნიშვნელობას კლასტერულ ინდექსში, მონაცემთა ბაზა იძულებული იქნება აღადგინოს ინდექსის ელემენტები (დალაგებული თანმიმდევრობით შესანახად). დაიმახსოვრეთ, კლასტერული ინდექსის ინდექსის ელემენტები შეიცავს სვეტის ყველა მნიშვნელობას, ამიტომ სვეტის მნიშვნელობის შეცვლა შედარებულია Delete განცხადების შესრულებასთან, რასაც მოჰყვება ჩასმა, რაც აშკარად გამოიწვევს მუშაობის პრობლემებს, თუ ეს ხშირად მოხდება. ამ მიზეზით, კლასტერული ინდექსები ხშირად შედგება ძირითადი გასაღებისა და უცხო გასაღების სვეტისგან. თუ ძირითადი მნიშვნელობები იცვლება, ისინი ძალიან იშვიათად იცვლება.

დასკვნა

მონაცემთა ბაზაში გამოსაყენებლად სწორი ინდექსების განსაზღვრა მოითხოვს სისტემის ფრთხილად ანალიზს და ტესტირებას. ამ სტატიაში წარმოდგენილი პრაქტიკა კარგი წესებია ინდექსების შესაქმნელად. ამ მეთოდების გამოყენების შემდეგ, თქვენ დაგჭირდებათ თქვენი კონკრეტული აპლიკაციის ხელახლა ტესტირება თქვენი სპეციფიკური ტექნიკის, მეხსიერების და ოპერაციების პირობებში.

ერთ-ერთი ყველაზე მნიშვნელოვანი გზა მაღალი პროდუქტიულობის მისაღწევად SQL სერვერიარის ინდექსების გამოყენება. ინდექსი აჩქარებს შეკითხვის პროცესს ცხრილის მონაცემების მწკრივებზე სწრაფი წვდომით, ისევე როგორც წიგნის ინდექსი დაგეხმარებათ სწრაფად იპოვოთ თქვენთვის საჭირო ინფორმაცია. ამ სტატიაში მე მივცემ მოკლე მიმოხილვას ინდექსების შესახებ SQL სერვერიდა აუხსენით, როგორ არის ორგანიზებული ისინი მონაცემთა ბაზაში და როგორ უწყობს ხელს მონაცემთა ბაზის მოთხოვნების დაჩქარებას.

ინდექსები იქმნება ცხრილისა და ხედვის სვეტებზე. ინდექსები იძლევა საშუალებას სწრაფად მოძებნოთ მონაცემები ამ სვეტების მნიშვნელობებზე დაყრდნობით. მაგალითად, თუ შექმნით ინდექსს პირველად გასაღებზე და შემდეგ მოძებნით მონაცემთა რიგს პირველადი გასაღების მნიშვნელობების გამოყენებით, მაშინ SQL სერვერიჯერ იპოვის ინდექსის მნიშვნელობას და შემდეგ გამოიყენებს ინდექსს მონაცემთა მთელი რიგის სწრაფად მოსაძებნად. ინდექსის გარეშე, შესრულდება ცხრილის ყველა მწკრივის სრული სკანირება, რამაც შეიძლება მნიშვნელოვანი გავლენა მოახდინოს შესრულებაზე.
თქვენ შეგიძლიათ შექმნათ ინდექსი ცხრილის ან ხედის უმეტეს სვეტებზე. გამონაკლისი არის ძირითადად სვეტები მონაცემთა ტიპებით დიდი ობიექტების შესანახად ( ლობი), როგორიცაა გამოსახულება, ტექსტიან ვარჩარი (მაქს). თქვენ ასევე შეგიძლიათ შექმნათ ინდექსები სვეტებზე, რომლებიც შექმნილია მონაცემების ფორმატში შესანახად XML, მაგრამ ეს ინდექსები ოდნავ განსხვავებულად არის სტრუქტურირებული, ვიდრე სტანდარტული და მათი განხილვა სცილდება ამ სტატიის ფარგლებს. ასევე, სტატიაში არ არის საუბარი სვეტების მაღაზიაინდექსები. ამის ნაცვლად, მე ყურადღებას ვამახვილებ იმ ინდექსებზე, რომლებიც ყველაზე ხშირად გამოიყენება მონაცემთა ბაზებში SQL სერვერი.
ინდექსი შედგება გვერდების ნაკრებისგან, ინდექსის კვანძებისგან, რომლებიც ორგანიზებულია ხის სტრუქტურაში - დაბალანსებული ხე. ეს სტრუქტურა იერარქიული ხასიათისაა და იწყება ფესვის კვანძით იერარქიის ზედა ნაწილში და ფოთლის კვანძებით, ფოთლებით, ბოლოში, როგორც ნაჩვენებია სურათზე:


როდესაც თქვენ კითხულობთ ინდექსირებულ სვეტს, შეკითხვის ძრავა იწყება ძირეული კვანძის ზედა ნაწილში და მიდის ქვემოთ შუალედური კვანძების გავლით, თითოეული შუალედური ფენა შეიცავს უფრო დეტალურ ინფორმაციას მონაცემთა შესახებ. შეკითხვის ძრავა აგრძელებს მოძრაობას ინდექსის კვანძებში, სანამ არ მიაღწევს ქვედა დონეს ინდექსის ფოთლებით. მაგალითად, თუ თქვენ ეძებთ მნიშვნელობას 123 ინდექსირებულ სვეტში, შეკითხვის ძრავა პირველ რიგში განსაზღვრავს გვერდს პირველ შუალედურ დონეზე root დონეზე. ამ შემთხვევაში, პირველი გვერდი მიუთითებს მნიშვნელობაზე 1-დან 100-მდე, ხოლო მეორე 101-დან 200-მდე, ასე რომ, შეკითხვის ძრავა მიიღებს წვდომას ამ შუალედური დონის მეორე გვერდზე. შემდეგ ნახავთ, რომ უნდა გადახვიდეთ შემდეგი საშუალო დონის მესამე გვერდზე. აქედან, შეკითხვის ქვესისტემა წაიკითხავს თავად ინდექსის მნიშვნელობას ქვედა დონეზე. ინდექსის ფურცლები შეიძლება შეიცავდეს ან თავად ცხრილის მონაცემებს ან უბრალოდ მაჩვენებელს ცხრილის მონაცემებით მწკრივებზე, რაც დამოკიდებულია ინდექსის ტიპზე: კლასტერული ინდექსი ან არაკლასტერული ინდექსი.

კლასტერული ინდექსი
კლასტერული ინდექსი ინახავს მონაცემების რეალურ რიგებს ინდექსის ფოთლებში. წინა მაგალითს რომ დავუბრუნდეთ, ეს ნიშნავს, რომ 123-ის საკვანძო მნიშვნელობასთან დაკავშირებული მონაცემთა რიგი შეინახება თავად ინდექსში. კლასტერული ინდექსის მნიშვნელოვანი მახასიათებელია ის, რომ ყველა მნიშვნელობა დალაგებულია კონკრეტული თანმიმდევრობით, აღმავალი ან დაღმავალი. ამიტომ, ცხრილს ან ხედს შეიძლება ჰქონდეს მხოლოდ ერთი კლასტერული ინდექსი. გარდა ამისა, უნდა აღინიშნოს, რომ ცხრილში მონაცემები ინახება დახარისხებული სახით მხოლოდ იმ შემთხვევაში, თუ ამ ცხრილში შეიქმნა კლასტერული ინდექსი.
ცხრილს, რომელსაც არ აქვს კლასტერული ინდექსი, ეწოდება გროვა.
არაკლასტერული ინდექსი
კლასტერული ინდექსისგან განსხვავებით, არაკლასტერული ინდექსის ფოთლები შეიცავს მხოლოდ იმ სვეტებს ( გასაღები) რომლითაც განისაზღვრება ეს ინდექსი და ასევე შეიცავს ცხრილის რეალური მონაცემების მქონე რიგების მაჩვენებელს. ეს ნიშნავს, რომ ქვემოკითხვის სისტემა მოითხოვს დამატებით ოპერაციას საჭირო მონაცემების მოსაძებნად და მოსაპოვებლად. მონაცემთა მაჩვენებლის შინაარსი დამოკიდებულია იმაზე, თუ როგორ ინახება მონაცემები: კლასტერული ცხრილი ან გროვა. თუ მაჩვენებელი მიუთითებს კლასტერულ ცხრილზე, ის მიუთითებს კლასტერულ ინდექსზე, რომელიც შეიძლება გამოყენებულ იქნას ფაქტობრივი მონაცემების მოსაძებნად. თუ მაჩვენებელი ეხება გროვას, მაშინ ის მიუთითებს მონაცემთა მწკრივის კონკრეტულ იდენტიფიკატორზე. არაკლასტერული ინდექსების დალაგება შეუძლებელია როგორც კლასტერული ინდექსები, მაგრამ შეგიძლიათ შექმნათ ერთზე მეტი არაკლასტერული ინდექსი მაგიდაზე ან ხედზე, 999-მდე. ეს არ ნიშნავს იმას, რომ თქვენ უნდა შექმნათ რაც შეიძლება მეტი ინდექსი. ინდექსებს შეუძლიათ გააუმჯობესონ ან შეამცირონ სისტემის მუშაობა. გარდა იმისა, რომ შეგიძლიათ შექმნათ მრავალი არაკლასტერული ინდექსი, თქვენ ასევე შეგიძლიათ შეიტანოთ დამატებითი სვეტები ( ჩართული სვეტი) მის ინდექსში: ინდექსის ფოთლები შეინახავს არა მხოლოდ თავად ინდექსირებული სვეტების მნიშვნელობას, არამედ ამ არაინდექსირებული დამატებითი სვეტების მნიშვნელობებს. ეს მიდგომა საშუალებას მოგცემთ გადალახოთ ინდექსზე დაყენებული ზოგიერთი შეზღუდვა. მაგალითად, შეგიძლიათ ჩართოთ არაინდექსირებადი სვეტი ან გვერდის ავლით ინდექსის სიგრძის ლიმიტი (900 ბაიტი უმეტეს შემთხვევაში).

ინდექსების სახეები

გარდა იმისა, რომ არის კლასტერული ან არაკლასტერული ინდექსი, ის შეიძლება შემდგომ კონფიგურირებული იყოს როგორც კომპოზიტური ინდექსი, უნიკალური ინდექსი ან დაფარვის ინდექსი.
კომპოზიტური ინდექსი
ასეთი ინდექსი შეიძლება შეიცავდეს ერთზე მეტ სვეტს. შეგიძლიათ ინდექსში შეიტანოთ 16-მდე სვეტი, მაგრამ მათი საერთო სიგრძე შემოიფარგლება 900 ბაიტით. როგორც კლასტერული, ასევე არაკლასტერული ინდექსები შეიძლება იყოს კომპოზიტური.
უნიკალური ინდექსი
ეს ინდექსი უზრუნველყოფს, რომ ინდექსირებული სვეტის თითოეული მნიშვნელობა უნიკალურია. თუ ინდექსი კომპოზიტურია, მაშინ უნიკალურობა ვრცელდება ინდექსის ყველა სვეტზე, მაგრამ არა თითოეულ ცალკეულ სვეტზე. მაგალითად, თუ შექმნით უნიკალურ ინდექსს სვეტებზე NAMEდა გვარი, მაშინ სრული სახელი უნდა იყოს უნიკალური, მაგრამ შესაძლებელია სახელის ან გვარის დუბლიკატი.
უნიკალური ინდექსი ავტომატურად იქმნება, როდესაც თქვენ განსაზღვრავთ სვეტის შეზღუდვას: პირველადი გასაღები ან უნიკალური მნიშვნელობის შეზღუდვა:
  • Მთავარი გასაღები
    როდესაც თქვენ განსაზღვრავთ ძირითადი გასაღების შეზღუდვას ერთ ან მეტ სვეტზე, მაშინ SQL სერვერიავტომატურად ქმნის უნიკალურ კლასტერულ ინდექსს, თუ ადრე არ იყო შექმნილი კლასტერული ინდექსი (ამ შემთხვევაში, პირველად გასაღებზე იქმნება უნიკალური არაკლასტერული ინდექსი)
  • ღირებულებების უნიკალურობა
    როდესაც თქვენ განსაზღვრავთ შეზღუდვას ღირებულებების უნიკალურობაზე, მაშინ SQL სერვერიავტომატურად ქმნის უნიკალურ არაკლასტერულ ინდექსს. შეგიძლიათ მიუთითოთ, რომ შეიქმნას უნიკალური კლასტერული ინდექსი, თუ მაგიდაზე ჯერ არ არის შექმნილი კლასტერული ინდექსი.
დაფარვის ინდექსი
ასეთი ინდექსი საშუალებას აძლევს კონკრეტულ შეკითხვას დაუყოვნებლივ მიიღოს ყველა საჭირო მონაცემი ინდექსის ფოთლებიდან, თავად ცხრილის ჩანაწერებზე დამატებითი წვდომის გარეშე.

ინდექსების დიზაინი

რამდენადაც სასარგებლოა ინდექსები, ისინი ყურადღებით უნდა იყოს შემუშავებული. იმის გამო, რომ ინდექსებმა შეიძლება დაიკავონ მნიშვნელოვანი ადგილი დისკზე, თქვენ არ გსურთ შექმნათ მეტი ინდექსი, ვიდრე საჭიროა. გარდა ამისა, ინდექსები ავტომატურად ახლდება მონაცემთა რიგის განახლებისას, რამაც შეიძლება გამოიწვიოს დამატებითი რესურსის ზედნადები და შესრულების დეგრადაცია. ინდექსების შედგენისას მხედველობაში უნდა იქნას მიღებული რამდენიმე მოსაზრება მონაცემთა ბაზასთან და მის წინააღმდეგ მიმართულ მოთხოვნებთან დაკავშირებით.
Მონაცემთა ბაზა
როგორც უკვე აღვნიშნეთ, ინდექსებს შეუძლიათ გააუმჯობესონ სისტემის მუშაობა, რადგან ისინი აწვდიან შეკითხვის სისტემას მონაცემთა მოძიების სწრაფ გზას. თუმცა, თქვენ ასევე უნდა გაითვალისწინოთ რამდენად ხშირად აპირებთ მონაცემების ჩასმას, განახლებას ან წაშლას. როდესაც თქვენ შეცვლით მონაცემებს, ინდექსები ასევე უნდა შეიცვალოს, რათა აისახოს შესაბამისი მოქმედებები მონაცემებზე, რამაც შეიძლება მნიშვნელოვნად შეამციროს სისტემის მუშაობა. ინდექსირების სტრატეგიის დაგეგმვისას გაითვალისწინეთ შემდეგი მითითებები:
  • ცხრილებისთვის, რომლებიც ხშირად განახლდება, გამოიყენეთ რაც შეიძლება ნაკლები ინდექსი.
  • თუ ცხრილი შეიცავს დიდი რაოდენობით მონაცემებს, მაგრამ ცვლილებები უმნიშვნელოა, გამოიყენეთ იმდენი ინდექსი, რამდენიც საჭიროა თქვენი მოთხოვნების შესრულების გასაუმჯობესებლად. თუმცა, მცირე მაგიდებზე ინდექსების გამოყენებამდე კარგად დაფიქრდით, რადგან... შესაძლებელია, რომ ინდექსის ძიების გამოყენებას შეიძლება მეტი დრო დასჭირდეს, ვიდრე უბრალოდ ყველა მწკრივის სკანირება.
  • კლასტერული ინდექსებისთვის შეეცადეთ შეინარჩუნოთ ველები რაც შეიძლება მოკლე. საუკეთესო მიდგომაა კლასტერული ინდექსის გამოყენება სვეტებზე, რომლებსაც აქვთ უნიკალური მნიშვნელობები და არ დაუშვებენ NULL-ს. სწორედ ამიტომ პირველადი გასაღები ხშირად გამოიყენება როგორც კლასტერული ინდექსი.
  • სვეტის მნიშვნელობების უნიკალურობა გავლენას ახდენს ინდექსის შესრულებაზე. ზოგადად, რაც უფრო მეტი დუბლიკატი გაქვთ სვეტში, მით უფრო უარესია ინდექსი. მეორეს მხრივ, რაც უფრო მეტი უნიკალური მნიშვნელობებია, მით უკეთესია ინდექსის შესრულება. შეძლებისდაგვარად გამოიყენეთ უნიკალური ინდექსი.
  • კომპოზიტური ინდექსისთვის, მხედველობაში მიიღება სვეტების თანმიმდევრობა ინდექსში. სვეტები, რომლებიც გამოიყენება გამონათქვამებში სად(Მაგალითად, WHERE FirstName = "ჩარლი") პირველ რიგში უნდა იყოს ინდექსში. შემდგომი სვეტები უნდა იყოს ჩამოთვლილი მათი მნიშვნელობების უნიკალურობიდან გამომდინარე (სვეტები ყველაზე მეტი უნიკალური მნიშვნელობებით პირველ ადგილზეა).
  • თქვენ ასევე შეგიძლიათ მიუთითოთ ინდექსი გამოთვლილ სვეტებზე, თუ ისინი აკმაყოფილებენ გარკვეულ მოთხოვნებს. მაგალითად, გამონათქვამები, რომლებიც გამოიყენება სვეტის მნიშვნელობის მისაღებად, უნდა იყოს განმსაზღვრელი (ყოველთვის აბრუნებს იგივე შედეგს შეყვანის პარამეტრების მოცემული ნაკრებისთვის).
მონაცემთა ბაზის მოთხოვნები
ინდექსების შედგენისას კიდევ ერთი გასათვალისწინებელია ის, თუ რა მოთხოვნები იმართება მონაცემთა ბაზის წინააღმდეგ. როგორც უკვე აღვნიშნეთ, უნდა გაითვალისწინოთ რამდენად ხშირად იცვლება მონაცემები. გარდა ამისა, უნდა იქნას გამოყენებული შემდეგი პრინციპები:
  • შეეცადეთ ჩასვათ ან შეცვალოთ რაც შეიძლება მეტი მწკრივი ერთ შეკითხვაში, ვიდრე ამის გაკეთება რამდენიმე ერთ მოთხოვნაში.
  • შექმენით არაკლასტერული ინდექსი სვეტებზე, რომლებიც ხშირად გამოიყენება საძიებო ტერმინებად თქვენს შეკითხვებში. სადდა კავშირები შეუერთდი.
  • განიხილეთ სვეტების ინდექსირება, რომლებიც გამოიყენება მწკრივების ძიებაში ზუსტი მნიშვნელობის შესატყვისებისთვის.

ახლა კი რეალურად:

14 შეკითხვა SQL Server-ში ინდექსების შესახებ, რომელთა დასმაც გრცხვენიათ

რატომ არ შეიძლება ცხრილს ჰქონდეს ორი კლასტერული ინდექსი?

გსურთ მოკლე პასუხი? კლასტერული ინდექსი არის ცხრილი. როდესაც თქვენ ქმნით კლასტერულ ინდექსს მაგიდაზე, შენახვის ძრავა ახარისხებს ცხრილის ყველა რიგს აღმავალი ან კლებადობით, ინდექსის განმარტების მიხედვით. კლასტერული ინდექსი არ არის ცალკეული ერთეული, როგორც სხვა ინდექსები, არამედ არის მექანიზმი, რომელიც აწესრიგებს მონაცემთა ცხრილში და ხელს უწყობს მონაცემთა მწკრივებზე სწრაფ წვდომას.
წარმოვიდგინოთ, რომ თქვენ გაქვთ ცხრილი, რომელიც შეიცავს გაყიდვების ტრანზაქციების ისტორიას. გაყიდვების ცხრილი შეიცავს ინფორმაციას, როგორიცაა შეკვეთის ID, პროდუქტის პოზიცია შეკვეთაში, პროდუქტის ნომერი, პროდუქტის რაოდენობა, შეკვეთის ნომერი და თარიღი და ა.შ. თქვენ ქმნით კლასტერულ ინდექსს სვეტებზე Შეკვეთის ნომერიდა LineID, დალაგებულია ზრდის მიხედვით, როგორც ნაჩვენებია შემდეგში T-SQLკოდი:
CREATE UNIQUE CLUSTERED INDEX ix_oriderid_lineid ON dbo.Sales(OrderID, LineID);
ამ სკრიპტის გაშვებისას, ცხრილის ყველა სტრიქონი ფიზიკურად იქნება დალაგებული ჯერ OrderID სვეტით და შემდეგ LineID-ით, მაგრამ თავად მონაცემები დარჩება ერთ ლოგიკურ ბლოკში, ცხრილში. ამ მიზეზით, თქვენ არ შეგიძლიათ შექმნათ ორი კლასტერული ინდექსი. შეიძლება იყოს მხოლოდ ერთი ცხრილი ერთი მონაცემით და ამ ცხრილის დალაგება შესაძლებელია მხოლოდ ერთხელ კონკრეტული თანმიმდევრობით.

თუ კლასტერული ცხრილი ბევრ სარგებელს იძლევა, მაშინ რატომ გამოვიყენოთ გროვა?

Მართალი ხარ. კლასტერული ცხრილები შესანიშნავია და თქვენი მოთხოვნების უმეტესობა უკეთესად შეასრულებს ცხრილებს, რომლებსაც აქვთ კლასტერული ინდექსი. მაგრამ ზოგიერთ შემთხვევაში შეიძლება დაგჭირდეთ მაგიდების დატოვება ბუნებრივ, ხელუხლებელ მდგომარეობაში, ე.ი. გროვის სახით და შექმენით მხოლოდ არაკლასტერული ინდექსები თქვენი მოთხოვნების გასაშვებად.
გროვა, როგორც გახსოვთ, ინახავს მონაცემებს შემთხვევითი თანმიმდევრობით. როგორც წესი, შენახვის ქვესისტემა ამატებს მონაცემებს ცხრილში იმ თანმიმდევრობით, რომლითაც ის არის ჩასმული, მაგრამ შენახვის ქვესისტემას ასევე მოსწონს რიგების გადაადგილება უფრო ეფექტური შენახვისთვის. შედეგად, თქვენ არ გაქვთ შანსი წინასწარ განსაზღვროთ, რა თანმიმდევრობით შეინახება მონაცემები.
თუ მოთხოვნის ძრავას სჭირდება მონაცემების პოვნა არაკლასტერული ინდექსის სარგებლობის გარეშე, ის გააკეთებს ცხრილის სრულ სკანირებას მისთვის საჭირო რიგების მოსაძებნად. ძალიან პატარა მაგიდებზე ეს ჩვეულებრივ პრობლემას არ წარმოადგენს, მაგრამ როგორც გროვა იზრდება ზომაში, შესრულება სწრაფად იკლებს. რა თქმა უნდა, არაკლასტერული ინდექსი დაგეხმარებათ ფაილის, გვერდისა და მწკრივის მაჩვენებლის გამოყენებით, სადაც ინახება საჭირო მონაცემები - ეს ჩვეულებრივ ბევრად უკეთესი ალტერნატივაა ცხრილის სკანირებისთვის. ასეც რომ იყოს, რთულია კლასტერული ინდექსის უპირატესობების შედარება შეკითხვის შესრულების განხილვისას.
თუმცა, გროვას შეუძლია გარკვეულ სიტუაციებში მუშაობის გაუმჯობესება. განვიხილოთ ცხრილი ბევრი ჩანართი, მაგრამ ცოტა განახლებები ან წაშლები. მაგალითად, ცხრილი, რომელიც ინახავს ჟურნალს, ძირითადად გამოიყენება მნიშვნელობების ჩასართავად, სანამ არ დაარქივდება. გროვაზე, თქვენ ვერ იხილავთ პეიჯინგის და მონაცემთა ფრაგმენტაციას, როგორც კლასტერული ინდექსის შემთხვევაში, რადგან რიგები უბრალოდ ემატება გროვის ბოლოს. გვერდების ზედმეტად გაყოფამ შეიძლება მნიშვნელოვანი გავლენა იქონიოს შესრულებაზე და არა კარგი თვალსაზრისით. ზოგადად, გროვა საშუალებას გაძლევთ ჩაწეროთ მონაცემები შედარებით უმტკივნეულოდ და თქვენ არ მოგიწევთ შენახვა და ტექნიკური ხარჯები, როგორც ეს კლასტერული ინდექსით.
მაგრამ მონაცემების განახლებისა და წაშლის ნაკლებობა არ უნდა ჩაითვალოს ერთადერთ მიზეზად. ასევე მნიშვნელოვანი ფაქტორია მონაცემთა ნიმუშის აღების მეთოდი. მაგალითად, არ უნდა გამოიყენოთ გროვა, თუ თქვენ ხშირად კითხულობთ მონაცემთა დიაპაზონს ან იმ მონაცემებს, რომლებსაც ხშირად კითხულობთ, სჭირდება დახარისხება ან დაჯგუფება.
ეს ყველაფერი ნიშნავს იმას, რომ თქვენ უნდა განიხილოთ გროვის გამოყენება მხოლოდ მაშინ, როდესაც მუშაობთ ძალიან პატარა ცხრილებთან, ან თქვენი მთელი ურთიერთქმედება მაგიდასთან შემოიფარგლება მხოლოდ მონაცემების ჩასმით და თქვენი მოთხოვნები ძალიან მარტივია (და თქვენ იყენებთ არაკლასტერულ ინდექსებს მაინც). წინააღმდეგ შემთხვევაში, დაიცავით კარგად შემუშავებული კლასტერული ინდექსი, როგორიცაა განსაზღვრული მარტივი აღმავალი კლავიშის ველზე, როგორც ფართოდ გამოყენებული სვეტი პირადობა.

როგორ შევცვალო ნაგულისხმევი ინდექსის შევსების ფაქტორი?

ინდექსის ნაგულისხმევი შევსების ფაქტორის შეცვლა ერთია. იმის გაგება, თუ როგორ მუშაობს ნაგულისხმევი თანაფარდობა, სხვა საკითხია. მაგრამ პირველი, გადადგით რამდენიმე ნაბიჯი უკან. ინდექსის შევსების ფაქტორი განსაზღვრავს გვერდის სივრცის რაოდენობას ინდექსის ქვედა დონეზე (ფოთლის დონეზე) შესანახად ახალი გვერდის შევსების დაწყებამდე. მაგალითად, თუ კოეფიციენტი დაყენებულია 90-ზე, მაშინ როდესაც ინდექსი გაიზრდება, ის დაიკავებს გვერდის 90%-ს და შემდეგ გადავა შემდეგ გვერდზე.
ნაგულისხმევად, ინდექსის შევსების ფაქტორის მნიშვნელობა არის SQL სერვერიარის 0, რაც იგივეა, რაც 100. შედეგად, ყველა ახალი ინდექსი ავტომატურად იღებს ამ პარამეტრს, თუ კონკრეტულად არ მიუთითებთ თქვენს კოდში მნიშვნელობას, რომელიც განსხვავდება სისტემის სტანდარტული მნიშვნელობისგან ან არ შეცვლით ნაგულისხმევ ქცევას. Შეგიძლია გამოიყენო SQL Server Management Studioნაგულისხმევი მნიშვნელობის დასარეგულირებლად ან სისტემის შენახული პროცედურის გასაშვებად sp_configure. მაგალითად, შემდეგი ნაკრები T-SQLბრძანება ადგენს კოეფიციენტის მნიშვნელობას 90-ზე (ჯერ უნდა გადახვიდეთ გაფართოებული პარამეტრების რეჟიმში):
EXEC sp_configure "მოწინავე ვარიანტების ჩვენება", 1; გადადით კონფიგურაციაზე; GO EXEC sp_configure "fill factor", 90; გადადით კონფიგურაციაზე; წადი
ინდექსის შევსების ფაქტორის მნიშვნელობის შეცვლის შემდეგ, თქვენ უნდა გადატვირთოთ სერვისი SQL სერვერი. ახლა შეგიძლიათ შეამოწმოთ მითითებული მნიშვნელობა 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 სერვერიგამოიყენებს იმ კოეფიციენტის მნიშვნელობას, რომლითაც ეს ინდექსი არსებობდა მის რესტრუქტურიზაციამდე. მაგალითად, შემდეგი ოპერაცია ALTER ინდექსიაღადგენს ჩვენ მიერ ახლახანს შექმნილ ინდექსს:
ALTER INDEX ix_people_lastname ON Person.Person REBUILD; GO SELECT fill_factor FROM sys.indexes WHERE object_id = object_id("Person.Person") AND name="ix_people_lastname";
როდესაც შევამოწმებთ შევსების ფაქტორის მნიშვნელობას, მივიღებთ მნიშვნელობას 80, რადგან ეს არის ის, რაც ჩვენ დავაზუსტეთ, როდესაც ჩვენ შევქმენით ინდექსი ბოლოს. ნაგულისხმევი მნიშვნელობა იგნორირებულია.
როგორც ხედავთ, ინდექსის შევსების ფაქტორის მნიშვნელობის შეცვლა არც ისე რთულია. გაცილებით რთულია მიმდინარე მნიშვნელობის ცოდნა და იმის გაგება, თუ როდის გამოიყენება იგი. თუ თქვენ ყოველთვის კონკრეტულად მიუთითებთ კოეფიციენტს ინდექსების შექმნისა და აღდგენისას, მაშინ ყოველთვის იცით კონკრეტული შედეგი. თუ თქვენ არ უნდა იდარდოთ იმაზე, რომ ვინმემ კვლავ არ გააფუჭოს სერვერის პარამეტრები, რაც გამოიწვევს ყველა ინდექსის აღდგენას სასაცილოდ დაბალი ინდექსის შევსების ფაქტორით.

შესაძლებელია თუ არა კლასტერული ინდექსის შექმნა სვეტზე, რომელიც შეიცავს დუბლიკატებს?

Კი და არა. დიახ, თქვენ შეგიძლიათ შექმნათ კლასტერული ინდექსი გასაღების სვეტზე, რომელიც შეიცავს დუბლიკატ მნიშვნელობებს. არა, საკვანძო სვეტის მნიშვნელობა არ შეიძლება დარჩეს არაუნიკალურ მდგომარეობაში. Ნება მომეცი აგიხსნა. თუ თქვენ შექმნით არაუნიკალურ კლასტერულ ინდექსს სვეტზე, შენახვის ძრავა ამატებს გამაერთიანებელს დუბლიკატულ მნიშვნელობას, რათა უზრუნველყოს უნიკალურობა და, შესაბამისად, შეძლოს თითოეული მწკრივის იდენტიფიცირება კლასტერულ ცხრილში.
მაგალითად, თქვენ შეიძლება გადაწყვიტოთ შექმნათ კლასტერული ინდექსი სვეტზე, რომელიც შეიცავს მომხმარებლის მონაცემებს Გვარიგვარის შენარჩუნება. სვეტი შეიცავს მნიშვნელობებს Franklin, Hancock, Washington და Smith. შემდეგ ისევ ჩასვით მნიშვნელობები ადამსი, ჰენკოკი, სმიტი და სმიტი. მაგრამ გასაღების სვეტის მნიშვნელობა უნიკალური უნდა იყოს, ამიტომ შენახვის ძრავა შეცვლის დუბლიკატების მნიშვნელობას ისე, რომ ისინი ასე გამოიყურებოდეს: Adams, Franklin, Hancock, Hancock1234, Washington, Smith, Smith4567 და Smith5678.
ერთი შეხედვით, ეს მიდგომა კარგად ჩანს, მაგრამ მთელი რიცხვი ზრდის გასაღების ზომას, რაც შეიძლება პრობლემად იქცეს, თუ დუბლიკატების დიდი რაოდენობაა და ეს მნიშვნელობები გახდება არაკლასტერული ინდექსის ან უცხოურის საფუძველი. საკვანძო მითითება. ამ მიზეზების გამო, ყოველთვის უნდა შეეცადოთ შექმნათ უნიკალური კლასტერული ინდექსები, როდესაც ეს შესაძლებელია. თუ ეს შეუძლებელია, მაშინ მაინც შეეცადეთ გამოიყენოთ სვეტები ძალიან მაღალი უნიკალური მნიშვნელობის შემცველობით.

როგორ ინახება ცხრილი, თუ კლასტერული ინდექსი არ არის შექმნილი?

SQL სერვერიმხარს უჭერს ორი ტიპის ცხრილებს: კლასტერულ ცხრილებს, რომლებსაც აქვთ დაჯგუფებული ინდექსი და გროვის ცხრილები ან უბრალოდ გროვები. კლასტერული ცხრილებისგან განსხვავებით, გროვაზე მონაცემები არანაირად არ არის დალაგებული. არსებითად, ეს არის მონაცემთა გროვა (გროვა). თუ ასეთ ცხრილს რიგს დაამატებთ, შენახვის ძრავა უბრალოდ დაამატებს მას გვერდის ბოლოს. როდესაც გვერდი ივსება მონაცემებით, ის დაემატება ახალ გვერდზე. უმეტეს შემთხვევაში, თქვენ გსურთ შექმნათ კლასტერული ინდექსი მაგიდაზე, რათა ისარგებლოთ დახარისხებად და შეკითხვის სიჩქარით (სცადეთ წარმოიდგინოთ ტელეფონის ნომრის მოძიება დაუხარისხებელ მისამართთა წიგნში). თუმცა, თუ აირჩევთ არ შექმნათ კლასტერული ინდექსი, თქვენ მაინც შეგიძლიათ შექმნათ არაკლასტერული ინდექსი გროვაზე. ამ შემთხვევაში, თითოეულ ინდექსის მწკრივს ექნება მაჩვენებელი გროვის მწკრივისკენ. ინდექსში შედის ფაილის ID, გვერდის ნომერი და მონაცემთა ხაზის ნომერი.

რა კავშირია მნიშვნელობის უნიკალურობის შეზღუდვებსა და ცხრილის ინდექსებთან პირველად გასაღებს შორის?

პირველადი გასაღები და უნიკალური შეზღუდვა უზრუნველყოფს, რომ სვეტის მნიშვნელობები უნიკალურია. თქვენ შეგიძლიათ შექმნათ მხოლოდ ერთი ძირითადი გასაღები ცხრილისთვის და ის არ შეიძლება შეიცავდეს მნიშვნელობებს NULL. თქვენ შეგიძლიათ შექმნათ რამდენიმე შეზღუდვა ცხრილისთვის მნიშვნელობის უნიკალურობაზე და თითოეულ მათგანს შეიძლება ჰქონდეს ერთი ჩანაწერი NULL.
პირველადი გასაღების შექმნისას, შენახვის ძრავა ასევე ქმნის უნიკალურ კლასტერულ ინდექსს, თუ კლასტერული ინდექსი უკვე არ არის შექმნილი. თუმცა, თქვენ შეგიძლიათ უგულებელყოთ ნაგულისხმევი ქცევა და შეიქმნება არაკლასტერული ინდექსი. თუ პირველადი გასაღების შექმნისას არსებობს კლასტერული ინდექსი, შეიქმნება უნიკალური არაკლასტერული ინდექსი.
როდესაც თქვენ ქმნით უნიკალურ შეზღუდვას, შენახვის ძრავა ქმნის უნიკალურ, არაკლასტერულ ინდექსს. თუმცა, შეგიძლიათ მიუთითოთ უნიკალური კლასტერული ინდექსის შექმნა, თუ ის ადრე არ იყო შექმნილი.
ზოგადად, უნიკალური მნიშვნელობის შეზღუდვა და უნიკალური ინდექსი ერთი და იგივეა.

რატომ ჰქვია კლასტერულ და არაკლასტერულ ინდექსებს B-tree SQL Server-ში?

ძირითადი ინდექსები SQL Server-ში, კლასტერული ან არაკლასტერული, ნაწილდება გვერდების ერთობლიობაში, რომელსაც ეწოდება ინდექსის კვანძები. ეს გვერდები ორგანიზებულია კონკრეტულ იერარქიაში ხის სტრუქტურით, რომელსაც ეწოდება დაბალანსებული ხე. ზედა დონეზე არის ფესვის კვანძი, ბოლოში არის ფოთლის კვანძები, ზედა და ქვედა დონეებს შორის შუალედური კვანძებით, როგორც ნაჩვენებია სურათზე:


ძირეული კვანძი უზრუნველყოფს მთავარ შესვლის წერტილს შეკითხვებისთვის, რომლებიც ცდილობენ ინდექსის მეშვეობით მონაცემების მოძიებას. ამ კვანძიდან დაწყებული, შეკითხვის ძრავა იწყებს ნავიგაციას იერარქიული სტრუქტურის ქვემოთ შესაბამის ფოთლის კვანძში, რომელიც შეიცავს მონაცემებს.
მაგალითად, წარმოიდგინეთ, რომ მიღებულია მოთხოვნა 82-ის საკვანძო მნიშვნელობის შემცველი რიგების შესარჩევად. შეკითხვის ქვესისტემა იწყებს მუშაობას ძირეული კვანძიდან, რომელიც ეხება შესაბამის შუალედურ კვანძს, ჩვენს შემთხვევაში 1-100. შუალედური კვანძიდან 1-100 ხდება გადასვლა 51-100 კვანძზე, იქიდან კი საბოლოო კვანძზე 76-100. თუ ეს არის კლასტერული ინდექსი, მაშინ კვანძის ფურცელი შეიცავს 82-ის ტოლი კლავიშთან დაკავშირებული მწკრივის მონაცემებს. თუ ეს არაჯგუფური ინდექსია, მაშინ ინდექსის ფურცელი შეიცავს მაჩვენებელს დაჯგუფებული ცხრილისკენ ან კონკრეტულ მწკრივში გროვა.

როგორ შეიძლება ინდექსმა გააუმჯობესოს შეკითხვის შესრულება, თუ თქვენ უნდა გაიაროთ ყველა ეს ინდექსის კვანძი?

პირველი, ინდექსები ყოველთვის არ აუმჯობესებენ შესრულებას. ძალიან ბევრი არასწორად შექმნილი ინდექსი აქცევს სისტემას ჭაობში და ამცირებს შეკითხვის შესრულებას. უფრო ზუსტია იმის თქმა, რომ თუ ინდექსები საგულდაგულოდ არის გამოყენებული, მათ შეუძლიათ მნიშვნელოვანი ეფექტურობის მიღწევა.
წარმოიდგინეთ უზარმაზარი წიგნი, რომელიც ეძღვნება შესრულების დარეგულირებას SQL სერვერი(ქაღალდის ვერსია და არა ელექტრონული ვერსია). წარმოიდგინეთ, რომ გსურთ იპოვოთ ინფორმაცია რესურსის მმართველის კონფიგურაციის შესახებ. შეგიძლიათ თითი გვერდ-გვერდ გადაათრიოთ მთელ წიგნში, ან გახსნათ სარჩევი და გაიგოთ ზუსტი გვერდის ნომერი იმ ინფორმაციით, რომელსაც ეძებთ (იმ პირობით, რომ წიგნი სწორად არის ინდექსირებული და შიგთავსს აქვს სწორი ინდექსები). ეს რა თქმა უნდა დაზოგავს მნიშვნელოვან დროს, მიუხედავად იმისა, რომ ჯერ უნდა შეხვიდეთ სრულიად განსხვავებულ სტრუქტურაზე (ინდექსი), რათა მიიღოთ თქვენთვის საჭირო ინფორმაცია პირველადი სტრუქტურიდან (წიგნიდან).
წიგნის ინდექსის მსგავსად, ინდექსი SQL სერვერისაშუალებას გაძლევთ შეასრულოთ ზუსტი მოთხოვნები თქვენთვის საჭირო მონაცემებზე, ნაცვლად იმისა, რომ სრულად დაასკანიროთ ცხრილში მოცემული ყველა მონაცემი. მცირე ცხრილებისთვის, სრული სკანირება, როგორც წესი, არ არის პრობლემა, მაგრამ დიდი ცხრილები იკავებს მონაცემთა ბევრ გვერდს, რამაც შეიძლება გამოიწვიოს მოთხოვნის შესრულების მნიშვნელოვანი დრო, თუ არ არსებობს ინდექსი, რომელიც საშუალებას მისცემს შეკითხვის ძრავას დაუყოვნებლივ მიიღოს მონაცემების სწორი მდებარეობა. წარმოიდგინეთ, რომ დაიკარგებით მრავალ დონის გზის გასაყარზე, მთავარი მეტროპოლიის წინ, რუქის გარეშე და თქვენ მიიღებთ იდეას.

თუ ინდექსები ძალიან დიდია, რატომ არ უნდა შექმნათ ერთი ყველა სვეტზე?

არც ერთი კარგი საქმე არ უნდა დარჩეს დაუსჯელი. ყოველ შემთხვევაში, ასეა ინდექსებთან დაკავშირებით. რა თქმა უნდა, ინდექსები მშვენივრად მუშაობს მანამ, სანამ თქვენ აწარმოებთ ოპერატორის მოძიების შეკითხვებს აირჩიეთ, მაგრამ როგორც კი დაიწყება ხშირი ზარები ოპერატორებთან INSERT, განახლებადა წაშლაასე რომ, ლანდშაფტი ძალიან სწრაფად იცვლება.
როდესაც თქვენ იწყებთ მონაცემთა მოთხოვნას ოპერატორის მიერ აირჩიეთ, შეკითხვის ძრავა პოულობს ინდექსს, მოძრაობს მის ხის სტრუქტურაში და აღმოაჩენს მონაცემებს, რომელსაც ეძებს. რა შეიძლება იყოს უფრო მარტივი? მაგრამ ყველაფერი იცვლება, თუ თქვენ წამოიწყებთ ცვლილების განცხადებას, როგორიცაა განახლება. დიახ, განცხადების პირველი ნაწილისთვის, შეკითხვის ძრავას შეუძლია კვლავ გამოიყენოს ინდექსი შეცვლილი მწკრივის დასადგენად - ეს კარგი ამბავია. და თუ ზედიზედ არის მონაცემების მარტივი ცვლილება, რომელიც არ იმოქმედებს საკვანძო სვეტების ცვლილებებზე, მაშინ ცვლილების პროცესი სრულიად უმტკივნეულო იქნება. მაგრამ რა მოხდება, თუ ცვლილება გამოიწვევს მონაცემების შემცველი გვერდების გაყოფას, ან საკვანძო სვეტის მნიშვნელობის შეცვლას, რაც იწვევს მის სხვა ინდექსის კვანძში გადატანას - ეს გამოიწვევს ინდექსს შესაძლოა საჭირო გახდეს რეორგანიზაცია, რომელიც გავლენას მოახდენს ყველა ასოცირებულ ინდექსზე და ოპერაციებზე. , რამაც გამოიწვია პროდუქტიულობის ფართო დაქვეითება.
მსგავსი პროცესები ხდება ოპერატორთან დარეკვისას წაშლა. ინდექსი დაგეხმარებათ წაშლილი მონაცემების დადგენაში, მაგრამ თავად მონაცემების წაშლამ შეიძლება გამოიწვიოს გვერდის შეცვლა. რაც შეეხება ოპერატორს INSERT, ყველა ინდექსის მთავარი მტერი: იწყებ დიდი რაოდენობით მონაცემების დამატებას, რაც იწვევს ინდექსების ცვლილებას და მათ რეორგანიზაციას და ყველა ზარალდება.
ასე რომ, გაითვალისწინეთ თქვენი მონაცემთა ბაზაში შეკითხვის ტიპები, როდესაც ფიქრობთ იმაზე, თუ რა ტიპის ინდექსები და რამდენი შექმნათ. მეტი არ ნიშნავს უკეთესს. ცხრილზე ახალი ინდექსის დამატებამდე გაითვალისწინეთ არა მხოლოდ ძირითადი მოთხოვნების ღირებულება, არამედ მოხმარებული დისკის სივრცის რაოდენობა, ფუნქციონირებისა და ინდექსების შენარჩუნების ღირებულება, რამაც შეიძლება გამოიწვიოს დომინოს ეფექტი სხვა ოპერაციებზე. თქვენი ინდექსის დიზაინის სტრატეგია თქვენი განხორციელების ერთ-ერთი ყველაზე მნიშვნელოვანი ასპექტია და უნდა მოიცავდეს ბევრ მოსაზრებას, ინდექსის ზომიდან, უნიკალური მნიშვნელობების რაოდენობამდე, მოთხოვნების ტიპებამდე, რომელსაც ინდექსი მხარს უჭერს.

აუცილებელია თუ არა სვეტზე კლასტერული ინდექსის შექმნა პირველადი გასაღებით?

თქვენ შეგიძლიათ შექმნათ კლასტერული ინდექსი ნებისმიერ სვეტზე, რომელიც აკმაყოფილებს საჭირო პირობებს. მართალია, კლასტერული ინდექსი და ძირითადი გასაღების შეზღუდვა შექმნილია ერთმანეთისთვის და არის სამოთხეში შექმნილი შესატყვისი, ასე რომ გესმოდეთ ის ფაქტი, რომ როდესაც პირველად შექმნით, მაშინ ავტომატურად შეიქმნება კლასტერული ინდექსი, თუ ის არ ყოფილა. ადრე შექმნილი. თუმცა, თქვენ შეიძლება გადაწყვიტოთ, რომ კლასტერული ინდექსი უკეთესად მუშაობს სხვაგან და ხშირად თქვენი გადაწყვეტილება გამართლებული იქნება.
კლასტერული ინდექსის მთავარი მიზანია თქვენი ცხრილის ყველა მწკრივის დალაგება ინდექსის განსაზღვრისას მითითებული გასაღების სვეტის მიხედვით. ეს უზრუნველყოფს სწრაფ ძიებას და მარტივ წვდომას ცხრილის მონაცემებზე.
ცხრილის პირველადი გასაღები შეიძლება იყოს კარგი არჩევანი, რადგან ის ცალსახად განსაზღვრავს ცხრილების თითოეულ რიგს დამატებითი მონაცემების დამატების გარეშე. ზოგიერთ შემთხვევაში, საუკეთესო არჩევანი იქნება სუროგატი პირველადი გასაღები, რომელიც არა მხოლოდ უნიკალურია, არამედ მცირე ზომისაც და რომლის მნიშვნელობებიც თანმიმდევრულად იზრდება, რაც ამ მნიშვნელობაზე დაფუძნებულ არაკლასტერულ ინდექსებს უფრო ეფექტურს ხდის. შეკითხვის ოპტიმიზატორს ასევე მოსწონს კლასტერული ინდექსისა და პირველადი გასაღების ეს კომბინაცია, რადგან ცხრილების შეერთება უფრო სწრაფია, ვიდრე სხვა გზით შეერთება, რომელიც არ იყენებს ძირითად გასაღებს და მასთან დაკავშირებულ კლასტერულ ინდექსს. როგორც ვთქვი, ეს სამოთხეში შექმნილი მატჩია.
თუმცა, და ბოლოს, აღსანიშნავია, რომ კლასტერული ინდექსის შექმნისას გასათვალისწინებელია რამდენიმე ასპექტი: რამდენი არაკლასტერული ინდექსი დაფუძნდება მასზე, რამდენად ხშირად შეიცვლება საკვანძო ინდექსის სვეტის მნიშვნელობა და რამდენად დიდი. როდესაც კლასტერული ინდექსის სვეტების მნიშვნელობები იცვლება ან ინდექსი არ მუშაობს ისე, როგორც მოსალოდნელია, მაშინ ცხრილის ყველა სხვა ინდექსზე შეიძლება გავლენა იქონიოს. კლასტერული ინდექსი უნდა ეფუძნებოდეს ყველაზე მდგრად სვეტს, რომლის მნიშვნელობები იზრდება კონკრეტული თანმიმდევრობით, მაგრამ არ იცვლება შემთხვევითი გზით. ინდექსმა უნდა მხარი დაუჭიროს შეკითხვებს ცხრილის ყველაზე ხშირად მისაწვდომ მონაცემებთან მიმართებაში, ამიტომ მოთხოვნები სრულად სარგებლობს იმით, რომ მონაცემები დალაგებულია და ხელმისაწვდომია ძირეულ კვანძებში, ინდექსის ფოთლებში. თუ პირველადი გასაღები შეესაბამება ამ სცენარს, მაშინ გამოიყენეთ იგი. თუ არა, მაშინ აირჩიეთ სვეტების სხვა ნაკრები.

რა მოხდება, თუ ხედის ინდექსირებას ახდენთ, ის მაინც ხედია?

ხედი არის ვირტუალური ცხრილი, რომელიც ქმნის მონაცემებს ერთი ან მეტი ცხრილიდან. არსებითად, ეს არის დასახელებული მოთხოვნა, რომელიც ამოიღებს მონაცემებს ძირითადი ცხრილებიდან, როდესაც თქვენ კითხულობთ ამ ხედს. თქვენ შეგიძლიათ გააუმჯობესოთ შეკითხვის შესრულება ამ ხედზე კლასტერული და არაკლასტერული ინდექსების შექმნით, ისევე, როგორც თქვენ ქმნით ინდექსებს მაგიდაზე, მაგრამ მთავარი გაფრთხილება ისაა, რომ ჯერ შექმნით კლასტერულ ინდექსს, შემდეგ კი შეგიძლიათ შექმნათ არაკლასტერული.
როდესაც იქმნება ინდექსირებული ხედი (მატერიალიზებული ხედი), მაშინ თავად ხედის განმარტება რჩება ცალკეულ ერთეულად. ყოველივე ამის შემდეგ, ეს მხოლოდ მყარი კოდირებული ოპერატორია აირჩიეთ, ინახება მონაცემთა ბაზაში. მაგრამ ინდექსი სრულიად განსხვავებული ამბავია. როდესაც პროვაიდერზე ქმნით კლასტერულ ან არაკლასტერულ ინდექსს, მონაცემები ფიზიკურად ინახება დისკზე, ისევე როგორც ჩვეულებრივი ინდექსი. გარდა ამისა, როდესაც მონაცემები იცვლება ძირითად ცხრილებში, ხედის ინდექსი ავტომატურად იცვლება (ეს ნიშნავს, რომ თქვენ შეიძლება თავიდან აიცილოთ ნახვების ინდექსირება ცხრილებზე, რომლებიც ხშირად იცვლება). ნებისმიერ შემთხვევაში, ხედი რჩება ხედად - ცხრილების ხედვა, მაგრამ ერთი შესრულებული მომენტში, მის შესაბამისი ინდექსებით.
სანამ ხედზე ინდექსის შექმნას შეძლებთ, ის უნდა აკმაყოფილებდეს რამდენიმე შეზღუდვას. მაგალითად, ხედს შეუძლია მიმართოს მხოლოდ ბაზის ცხრილებს, მაგრამ არა სხვა ხედებს და ეს ცხრილები უნდა იყოს იმავე მონაცემთა ბაზაში. სინამდვილეში ბევრი სხვა შეზღუდვაა, ასე რომ, დარწმუნდით, რომ შეამოწმეთ დოკუმენტაცია SQL სერვერიყველა ბინძური დეტალისთვის.

რატომ გამოვიყენოთ დაფარვის ინდექსი კომპოზიტური ინდექსის ნაცვლად?

პირველ რიგში, მოდით დავრწმუნდეთ, რომ გვესმის განსხვავება ამ ორს შორის. რთული ინდექსი არის ჩვეულებრივი ინდექსი, რომელიც შეიცავს ერთზე მეტ სვეტს. მრავალი საკვანძო სვეტი შეიძლება გამოყენებულ იქნას იმის უზრუნველსაყოფად, რომ ცხრილის თითოეული მწკრივი უნიკალურია, ან შეიძლება გქონდეთ რამდენიმე სვეტი, რათა დარწმუნდეთ, რომ პირველადი გასაღები უნიკალურია, ან შეიძლება ცდილობთ ოპტიმიზაციას გაუწიოთ ხშირად გამოძახებული მოთხოვნების შესრულება მრავალ სვეტზე. ზოგადად, რაც უფრო მეტ საკვანძო სვეტს შეიცავს ინდექსი, მით უფრო ნაკლებად ეფექტური იქნება ინდექსი, რაც ნიშნავს, რომ კომპოზიტური ინდექსები გონივრულად უნდა იქნას გამოყენებული.
როგორც აღინიშნა, შეკითხვას შეუძლია დიდი სარგებლობა მოახდინოს, თუ ყველა საჭირო მონაცემი დაუყოვნებლივ განთავსდება ინდექსის ფოთლებზე, ისევე როგორც თავად ინდექსი. ეს არ არის პრობლემა კლასტერული ინდექსისთვის, რადგან ყველა მონაცემი უკვე არსებობს (ამიტომ მნიშვნელოვანია, რომ ყურადღებით იფიქროთ კლასტერული ინდექსის შექმნისას). მაგრამ ფოთლებზე არაჯგუფური ინდექსი შეიცავს მხოლოდ საკვანძო სვეტებს. ყველა სხვა მონაცემზე წვდომისთვის, შეკითხვის ოპტიმიზატორი საჭიროებს დამატებით ნაბიჯებს, რომლებსაც შეუძლიათ მნიშვნელოვანი ზედნადების დამატება თქვენი მოთხოვნების შესრულებაზე.
სწორედ აქ მოდის დაფარვის ინდექსი სამაშველოში. როდესაც თქვენ განსაზღვრავთ არაკლასტერულ ინდექსს, შეგიძლიათ მიუთითოთ დამატებითი სვეტები თქვენი საკვანძო სვეტებისთვის. მაგალითად, ვთქვათ, თქვენი აპლიკაცია ხშირად ითხოვს სვეტის მონაცემებს Შეკვეთის ნომერიდა Შეკვეთის თარიღიმაგიდაზე Გაყიდვების:
SELECT OrderID, OrderDate FROM Sales WHERE OrderID = 12345;
თქვენ შეგიძლიათ შექმნათ რთული არაკლასტერული ინდექსი ორივე სვეტზე, მაგრამ OrderDate სვეტი დაამატებს მხოლოდ ინდექსის შენარჩუნების ზედნადებს, განსაკუთრებით სასარგებლო კლავიშის სვეტის გარეშე. საუკეთესო გამოსავალი იქნება საკვანძო სვეტზე დაფარვის ინდექსის შექმნა Შეკვეთის ნომერიდა დამატებით ჩართული სვეტი Შეკვეთის თარიღი:
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 სერვერიაწესებს რამდენიმე შეზღუდვას გაფილტვრად ინდექსებზე, მაგალითად, ხედზე ფილტრირებადი ინდექსის შექმნის შეუძლებლობა, ამიტომ ყურადღებით წაიკითხეთ დოკუმენტაცია.
შეიძლება ასევე იყოს ის, რომ თქვენ შეგიძლიათ მიაღწიოთ მსგავს შედეგებს ინდექსირებული ხედის შექმნით. თუმცა, გაფილტრულ ინდექსს აქვს რამდენიმე უპირატესობა, როგორიცაა შენარჩუნების ხარჯების შემცირების შესაძლებლობა და თქვენი შესრულების გეგმების ხარისხის გაუმჯობესება. გაფილტრული ინდექსების აღდგენა შესაძლებელია ონლაინ რეჟიმში. სცადეთ ეს ინდექსირებული ხედით.

და ისევ ცოტა მთარგმნელისგან

Habrahabr-ის გვერდებზე ამ თარგმანის გამოჩენის მიზანი იყო მოგიყვეთ ან შეგახსენოთ SimpleTalk ბლოგის შესახებ. RedGate.
ის აქვეყნებს ბევრ გასართობ და საინტერესო პოსტს.
მე არ ვარ ასოცირებული რომელიმე კომპანიის პროდუქტთან RedGateარც მათი გაყიდვით.

როგორც დაგპირდით, წიგნები მათთვის, ვისაც სურს მეტი იცოდეს
მე გირჩევთ სამ ძალიან კარგ წიგნს ჩემგან (ბმულები მივყავართ აანთებსვერსიები მაღაზიაში ამაზონი):

პრინციპში, შეგიძლიათ გახსნათ მარტივი ინდექსები
  • დამწყებთათვის
  • ინდექსი
  • ტეგების დამატება
    Microsoft SQL Server 2012 T-SQL საფუძვლები (დეველოპერის მითითება)
    ავტორი იციკ ბენ-განი
    გამოცემის თარიღი: 2012 წლის 15 ივლისი
    ავტორი, თავისი საქმის ოსტატი, გვაწვდის საბაზისო ცოდნას მონაცემთა ბაზებთან მუშაობის შესახებ.
    თუ ყველაფერი დაგავიწყდათ ან არასოდეს იცოდით, ნამდვილად ღირს წაკითხვა.

    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-ხის ინდექსით ინდექსირებისთვის, მაგრამ სვეტი, რომელიც არ აკმაყოფილებს ამ მოთხოვნებს, კარგი კანდიდატია, თუ მისი რიგების დაახლოებით 10% შეიცავს იდენტურ მნიშვნელობებს. და მეტი არა. „გადამრთველი“ ან „დროშის“ სვეტები, მაგალითად, ისინი, რომლებიც ინახავს ინფორმაციას პირის სქესის შესახებ, არ არის შესაფერისი B-ხის ინდექსებისთვის. სვეტები, რომლებიც გამოიყენება მცირე რაოდენობის „სანდო მნიშვნელობების“ შესანახად, ისევე როგორც ის, რომ ინახავს. გარკვეული მნიშვნელობები ასევე არ არის შესაფერისი. შემდეგ ნიშნები, მაგალითად, "სანდოობა" ან "არასანდო", "აქტიურობა" ან "უმოქმედობა", "დიახ" ან "არა" და ა.შ. და ა.შ. და ბოლოს, ინდექსები საპირისპირო კლავიშებით არის გამოიყენება, როგორც წესი, იქ, სადაც არის დამონტაჟებული და მუშაობს Oracleპარალელური სერვერი და თქვენ უნდა გაზარდოთ პარალელურობის დონე მონაცემთა ბაზაში მაქსიმუმამდე.