Novo

Forum kao aplikacija na telefonu

Dodajte forum na početni ekran i koristite ga kao aplikaciju, sa menijem na dnu ekrana.

  • 13 odgovora
  • 5.476 pregleda

Najnovija ↓

MS SQL - ignoriranje indeksa?! 22.07.2017. u 13:11 · pre 112 meseci #1
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?
Re: MS SQL - ignoriranje indeksa?! 22.07.2017. u 13:15 · pre 112 meseci #3
OK, ali ovdje je riječ o pretpostavci da se pretražuje po istoj koloni. To nisam napomenuo.
Re: MS SQL - ignoriranje indeksa?! 22.07.2017. u 13:21 · pre 112 meseci #4
Ili na primer (ID je indeksiran):
Code:

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

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

Re: MS SQL - ignoriranje indeksa?! 22.07.2017. u 13:23 · pre 112 meseci #5
Š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.
Re: MS SQL - ignoriranje indeksa?! 22.07.2017. u 13:29 · pre 112 meseci #6
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.
Re: MS SQL - ignoriranje indeksa?! 22.07.2017. u 15:02 · pre 112 meseci #7
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.
Potpis
Please do not feed the Trolls!

Blasphemy? How can I blaspheme? I'm a god!'
Sviđa mi se1
Re: MS SQL - ignoriranje indeksa?! 23.07.2017. u 13:01 · pre 112 meseci #8
Jos jedan u listi razloga zasto su "select * ..." upiti potpuni fail.

Potpis
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
Re: MS SQL - ignoriranje indeksa?! 23.07.2017. u 22:26 · pre 112 meseci #9
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.... :)
Potpis
Please do not feed the Trolls!

Blasphemy? How can I blaspheme? I'm a god!'
Re: MS SQL - ignoriranje indeksa?! 23.07.2017. u 23:07 · pre 112 meseci
izmenjeno 1 put, poslednji put itf 23.07.2017. u 23:37
  1. itf23.07.2017. u 23:37zapis iz teksta poruke
#10
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.
Re: MS SQL - ignoriranje indeksa?! 24.07.2017. u 11:19 · pre 112 meseci #11
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.
Potpis
Please do not feed the Trolls!

Blasphemy? How can I blaspheme? I'm a god!'
Re: MS SQL - ignoriranje indeksa?! 24.07.2017. u 11:45 · pre 112 meseci #12
@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.
Re: MS SQL - ignoriranje indeksa?! 25.07.2017. u 09:37 · pre 112 meseci #13
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.
Re: MS SQL - ignoriranje indeksa?! 26.07.2017. u 17:30 · pre 112 meseci #14
Inače, da li je potrebno reorganizirati/rebuildati neklasterirane indekse nakon što se naknadno doda/promijeni klasterirani indeks? Ili se to događa automatski?
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme