[ itf @ 22.07.2017. 12:11 ] @
Pročitao sam u SQL Server bibliji da SQL Query Optimizer pri izradi execution plan-a može odlučiti ignorirati indekse i umjesto skeniranja indeksa napraviti skeniranje tablice da bi pronašao traženi podatak. To mi malo zvuči nelogično jer još nisam vidio/čuo za slučaj da skeniranje tablice može dati bolje performanse od skeniranja indeksa, osim ako se baš slučajno ne potrefi da je traženi podatak negdje na samom vrhu. Ima itko možda kakav primjer za tu tezu?
[ Branimir Maksimovic @ 22.07.2017. 12:13 ] @
Pa glupo, ali ako dignes index nad polje1 a grupises po polje2 ;)
[ itf @ 22.07.2017. 12:15 ] @
OK, ali ovdje je riječ o pretpostavci da se pretražuje po istoj koloni. To nisam napomenuo.
[ dusans @ 22.07.2017. 12:21 ] @
Ili na primer (ID je indeksiran):
Code:

SELECT *
FROM tabela
WHERE (ID % 12345 = 777)

SELECT *
FROM tabela
WHERE (ID + Total = 23)

[ dusans @ 22.07.2017. 12:23 ] @
Šta znači pretražuje? Znaš, postoje kriterijumi koji nisu samo <, >, =

Citat:

The optimizer is convinced that if it's going to have to go back to the disk for retrieving column data anyway,
it might as well scan the table in the first place, since that'll be less work for it to do.
[ itf @ 22.07.2017. 12:29 ] @
Da. Sad sam našao još jedan primjer:

Citat:
For example, if 60 percent of the customers are in New York City, then selecting all customers in NYC will likely be faster with a table scan than with an index seek. However, to find the single customer from Delavan, Wisconsin, the query definitely needs the help of an index.
[ nkrgovic @ 22.07.2017. 14:02 ] @
Radi se o proceni optimiser-a vezanoj sta treba da vrati. Pretpostavimo da imas prost upit, koji ide ama bas po indexu:

SELECT * FROM KORISNIK WHERE POSTANSKI_BROJ=11000 ;

Ovde to funkcionise ovako:

- Uzmi index, nadji sve ID-eve gde je POSTANSKI_BROJ jednak zadatoj integer vrednosti.
- Udji u tablespace i po svakom indexu izvuci ceo slog i vrati ga kao deo rezultata.

U praksi, osim ako nemas covering index, negde kad result set bude vec 10% celog tablespace-a, brze je citati celu tabelu i on-the-fly vaditi rezultate, nego se setati sa indexom, pa cupati redove po indexu.

Sustina je da ti nemas sken tabele vs scan indexa. Ti imas scan tabele vs scan indexa + cupanje rezultatat po svakom nadjenom rezultatu za index.
[ mmix @ 23.07.2017. 12:01 ] @
Jos jedan u listi razloga zasto su "select * ..." upiti potpuni fail.

[ nkrgovic @ 23.07.2017. 21:26 ] @
Citat:
mmix: Jos jedan u listi razloga zasto su "select * ..." upiti potpuni fail.

Joj, nemoj da ides tamo. Cak i da ignorises ceo koncept ORM-ova i automatskog generisanja upita, opet je veliko pitanje da li mozes da imas sve upite pokrivene covering index-ima.... Da, super je to, ali to sto ne platis na mostu (SELECT-u) platis debelo na cupriji (INSERT/UPDATE). Jednom kad dobijes par desetina miliona redova u tabeli pokrivanje svih mogucih upita covering indexima, a da se pri tome tabela cesto pise, postane jako, jako bolno.

OK, moze se i to izbeci: Pravis kratke tabele. Nema par desetina kolona vec, realno, svega nekoliko, pa onda mozes da sve proste SELECT-ove pokrivas covering indexima i ne boli previse. E, ali onda nemas sve sto ti treba za upit u tabeli. Lepa ti je schema, normalizovana, sve stoji, imas elegantnih par JOIN-ova da ti izvuku podatke, a onda shvatis da storage engine ne ume da uradi ni right join po primarnom kljucu za pet tabela, vec mora da radi full table scan. Obrni, okreni, NEGDE moras da platis.

Tako da, nije nama dosadno, igranka bez prestanka.... :)
[ itf @ 23.07.2017. 22:07 ] @
Citat:
Sustina je da ti nemas sken tabele vs scan indexa. Ti imas scan tabele vs scan indexa + cupanje rezultatat po svakom nadjenom rezultatu za index.

Upravo zbog ovog boldanog sam i otvorio ovu temu jer mi je nelogično da unatoč toj stavci index scan može biti brži od table scan-a. Realno, oba će pročitati cijelu tablicu, ali index scan dodatno mora dohvatiti svaki zapis tablice po adresi u indeksu.. Ako je riječ o klasteriranom onda je sama tablica zapravo indeks pa bi trebalo biti isto, ali ako je indeks ne-klasterirani onda bih definitivno očekivao da index scan bude sporiji nego table scan.

[Ovu poruku je menjao itf dana 23.07.2017. u 23:37 GMT+1]
[ nkrgovic @ 24.07.2017. 10:19 ] @
Gledaj, ako odes u extrem, i zamislis scenario u kome je result set 100%, onda ti je, nadam se, jasno da je brze procitati celu tabelu, nego prvo procitati ceo index, pa onda citati red po red iz cele date? :)

Jednom kad ti to bude logicno, onda ti je jasno da pitanje nije "da li je efikasnije ici u index", vec samo "na kom procentu date postaje efikasnije ne ici u index" :D A kad to shvatis onda ti je jasno da je u pitanju samo cifra koju treba odrediti empirijski / merenjima.
[ djoka_l @ 24.07.2017. 10:45 ] @
@itf

Ne razumem šta ti nije jasno. Uzmi prost primer: prosečna dužina sloga neke tabele je, na primer 500 bajtova, dok je prosečna dužina indeksa nad tabelom 50 bajtova.

1. podaci iz baze se čitaju po DB blokovima, znači jednim čitanjem indeksa dohvati se 10 puta više indeksa nego redova tabele.
2. uzmimo primer: tabela je smeštena u 1000 blokova, a potrebna su tri reda. Preko indeksa (koji, na primer, ima 150 blokova), a pod uslovom da se ta tri reda nalazi u tri bloka, pročitaćemo 153 bloka, a full table scan će pročitati 1000 blokova.
3. physical read vs logical read - u kešu se nalaze neki blokovi, a keš je ograničen. Veća je verovatnoća da će u kešu (u RAM-u) biti blok sa indeksima nego blok sa podacima. U tom slučaju, indeks se i ne čita sa diska nego sa RAM-a
4. e sad kontra primer: za čitanje 1000 podataka, u najgorem slučaju možemo imati situaciju da je svaki od tih podataka u posebnom bloku. Tada bi index scan morao da pročita 150 blokova indeksa + 1000 blokova tabele, pa je pametnije raditi table scan nego index scan.
[ itf @ 25.07.2017. 08:37 ] @
Evo, uzmimo za primjer sljedeću situaciju:

SELECT * FROM tTablica

Ukoliko tTablica nema nikakav indeks onda se događa skeniranje tablice. Međutim, ukoliko tablica ima klasterirani indeks nad nekom kolonom događa se clustered index scan. Zašto index scan a ne table scan jer mi se čini da oba u ovom slučaju rade isto tj. prolaze kroz cijelu tablicu? Da li postoji nekakav konkretan razlog zašto je QO sada odabrao index scan a ne table scan?

S druge strane, da je taj indeks ne-klasterirani dogodio bi, logično, table scan.
[ itf @ 26.07.2017. 16:30 ] @
Inače, da li je potrebno reorganizirati/rebuildati neklasterirane indekse nakon što se naknadno doda/promijeni klasterirani indeks? Ili se to događa automatski?