Думите са доста логични и ще ги научите доста бързо. :)
Казано на лаик, SEEK предполага търсене на точни местоположения за записи, което прави SQL Server, когато колоната, в която търсите, е индексирана и вашият филтър (условието WHERE) е достатъчно точен.
СКАНИРАНЕ означава по-голям диапазон от редове, при които програмата за планиране на изпълнението на заявката преценява, че е по-бързо да извлече цял диапазон, за разлика от индивидуалното търсене на всяка стойност.
И да, можете да имате множество индекси в едно и също поле и понякога това може да е много добра идея. Играйте с индексите и използвайте планера за изпълнение на заявки, за да определите какво ще се случи (пряк път в SSMS:Ctrl + M). Можете дори да стартирате две версии на една и съща заявка и инструментът за планиране на изпълнението лесно ще ви покаже колко ресурси и време отнема всяка, което прави оптимизацията доста лесна.
Но за да ги разширим малко, кажете, че имате адресна таблица като тази и тя има над 1 милиард записа:
CREATE TABLE ADDRESS
(ADDRESS_ID INT -- CLUSTERED primary key ADRESS_PK_IDX
, PERSON_ID INT -- FOREIGN KEY, NONCLUSTERED INDEX ADDRESS_PERSON_IDX
, CITY VARCHAR(256)
, MARKED_FOR_CHECKUP BIT
, **+n^10 different other columns...**)
Сега, ако искате да намерите цялата адресна информация за лице 12345, индексът на PERSON_ID е идеален. Тъй като таблицата има много други данни на същия ред, би било неефективно и отнемащо място да се създаде неклъстъриран индекс, който да покрива всички други колони, както и PERSON_ID. В този случай SQL Server ще изпълни индекс SEEK на индекса в PERSON_ID, след което ще го използва, за да направи търсене на ключ на клъстерирания индекс в ADDRESS_ID и оттам ще върне всички данни във всички други колони на същия ред.
Кажете обаче, че искате да търсите всички хора в даден град, но не ви трябва друга адресна информация. Този път най-ефективният начин би бил да създадете индекс на CITY и да използвате опцията INCLUDE, за да обхванете и PERSON_ID. По този начин едно търсене/сканиране на индекс ще върне цялата информация, от която се нуждаете, без да е необходимо да прибягвате до проверка на CLUSTERED индекса за данните PERSON_ID на същия ред.
Сега, да кажем, че и двете заявки са необходими, но все още са доста тежки поради 1 милиарда записа. Но има една специална заявка, която трябва да бъде наистина много бърза. Тази заявка иска всички лица на адреси, които са MARKED_FOR_CHECKUP и които трябва да живеят в Ню Йорк (игнорирайте каквото и да означава проверка, това няма значение). Сега може да искате да създадете трети, филтриран индекс на MARKED_FOR_CHECKUP и CITY, с INCLUDE, покриващ PERSON_ID, и с филтър, казващ CITY ='Ню Йорк' и MARKED_FOR_CHECKUP =1. Този индекс ще бъде безумно бърз, тъй като винаги покрива само заявки които отговарят на тези точни условия и следователно трябва да преминат част от данните в сравнение с другите индекси.
(Отказ от отговорност тук, имайте предвид, че плановщикът за изпълнение на заявки не е глупав, той може да използва множество неклъстерирани индекси заедно, за да произведе правилните резултати, така че примерите по-горе може да не са най-добрите налични, тъй като е много трудно да си представите кога ще имате нужда 3 различни индекса, покриващи една и съща колона, но съм сигурен, че схващате идеята.)
Типовете индекси, техните колони, включени колони, редове за сортиране, филтри и т.н. зависят изцяло от ситуацията. Ще трябва да направите покриващи индекси, за да удовлетворите няколко различни типа заявки, както и персонализирани индекси, създадени специално за отделни, важни заявки. Всеки индекс заема място на твърдия диск, така че правенето на безполезни индекси е разточително и изисква допълнителна поддръжка, когато моделът на данните се промени, и губи време в операции за дефрагментиране и актуализиране на статистиката... така че не искате просто да налагате индекс на всичко или.
Експериментирайте, учете и открийте кое работи най-добре за вашите нужди.