sql >> Database teknologi >  >> RDS >> Sqlserver

Hvorfor er dette en indeksscanning og ikke en indekssøgning?

Den bruger primært en indeksscanning, fordi den også bruger en Merge Join. Merge Join-operatøren kræver to inputstrømme, der begge er sorteret i en rækkefølge, der er kompatibel med Join-betingelserne.

Og den bruger Merge Join-operatøren til at realisere din INNER JOIN, fordi den mener, at den vil være hurtigere end den mere typiske Nested Loop Join-operatør. Og det er nok rigtigt (det er det som regel), ved at bruge de to indekser, det har valgt, har det input-streams, der begge er forhåndssorteret efter din join-betingelse (LocationID). Når inputstrømmene er forhåndssorteret på denne måde, er Merge Joins næsten altid hurtigere end de to andre (Loop og Hash Joins).

Ulempen er, hvad du har bemærket:det ser ud til at scanne hele indekset ind, så hvordan kan det være hurtigere, hvis det læser så mange poster, som måske aldrig bliver brugt? Svaret er, at scanninger (på grund af deres sekventielle karakter) kan læse alt fra 10 til 100 gange så mange poster/sekund som søgninger.

Now Seeks vinder normalt, fordi de er selektive:de får kun de rækker, du beder om, mens scanninger er ikke-selektive:de skal returnere hver række i intervallet. Men fordi scanninger har meget højere læsehastighed, kan de ofte slå Seeks, så længe forholdet mellem kasserede rækker og matchende rækker er lavere end forholdet mellem Scan rækker/sek VS. Søg rækker/sek.

Spørgsmål?

OK, jeg er blevet bedt om at forklare den sidste sætning mere:

En "Discarded Row" er en, som scanningen læser (fordi den skal læse alt i indekset), men som vil blive afvist af Merge Join-operatøren, fordi den ikke har et match på den anden side, muligvis fordi WHERE-klausulens betingelse har allerede udelukket det.

"Matching Rows" er dem, der står, som faktisk er matchet med noget i Merge Join. Det er de samme rækker, som ville være blevet læst af en søgning, hvis scanningen blev erstattet af en søgning.

Du kan finde ud af, hvad der er, ved at se på statistikken i Forespørgselsplanen. Ser du den store fede pil til venstre for indeksscanningen? Det repræsenterer, hvor mange rækker optimeringsværktøjet tror, ​​at det vil læse med Scan. Statistikfeltet i den indeksscanning, som du har lagt ud, viser, at de faktiske rækker, der returneres, er omkring 5,4 mio. (5.394.402). Dette er lig med:

TotalScanRows = (MatchingRows + DiscardedRows)

(I hvert fald efter mine vilkår). For at få de matchende rækker, se på "Faktiske rækker" rapporteret af Merge Join-operatøren (du skal muligvis tage de TOP 100 af for at få dette præcist). Når du ved dette, kan du få de kasserede rækker ved at:

DiscardedRows = (TotalScanRows - MatchingRows)

Og nu kan du beregne forholdet.



  1. PDF oprettet med FPDF og hvordan du gemmer og henter pdf'en

  2. Hvordan får man kun numeriske kolonneværdier?

  3. Med PHP skal du trække en mængde fra en mysql-tabel

  4. Kan ikke få mysqldump til at oprette forbindelse til lokal mysql-instans (fejl 2003 / 10061)