Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Защо това е сканиране на индекс, а не търсене на индекс?

Той използва сканиране на индекс основно, защото използва и свързване чрез сливане. Операторът Merge Join изисква два входни потока, които са сортирани в ред, който е съвместим с условията на Join.

И използва оператора Merge Join, за да реализира вашия INNER JOIN, защото вярва, че това ще бъде по-бързо от по-типичния оператор Nested Loop Join. И вероятно е правилно (обикновено е), като използва двата индекса, които е избрал, има входни потоци, които са предварително сортирани според вашето условие за присъединяване (LocationID). Когато входните потоци са предварително сортирани по този начин, тогава обединяванията почти винаги са по-бързи от другите два (циклични и хеширащи присъединявания).

Недостатъкът е това, което забелязахте:изглежда, че сканира целия индекс, така че как може да бъде по-бързо, ако чете толкова много записи, които може никога да не бъдат използвани? Отговорът е, че сканиранията (поради тяхната последователна природа) могат да четат от 10 до 100 пъти повече записи/секунда, отколкото търсенията.

Now Seeks обикновено печелят, защото са селективни:те получават само редовете, които поискате, докато сканиранията не са селективни:те трябва да върнат всеки ред в диапазона. Но тъй като сканиранията имат много по-висока скорост на четене, те често могат да победят търсенията, стига съотношението на отхвърлените редове към съответстващите редове да е по-ниско отколкото съотношението сканирани редове/сек VS. Търсене на редове/сек.

Въпроси?

Добре, помолиха ме да обясня последното изречение повече:

„Отхвърлен ред“ е този, който сканирането чете (защото трябва да прочете всичко в индекса), но това ще бъде отхвърлено от оператора Merge Join, защото няма съвпадение от другата страна, вероятно защото Условието на клауза WHERE вече го е изключило.

„Съвпадащи редове“ са тези, които той прочете, които всъщност съответстват на нещо в Merge Join. Това са същите редове, които биха били прочетени от Seek, ако сканирането беше заменено от Seek.

Можете да разберете какво има, като погледнете статистиката в плана за заявка. Виждате ли онази огромна дебела стрелка вляво от сканирането на индекса? Това представлява колко реда оптимизаторът смята, че ще прочете със сканирането. Полето със статистика на сканирането на индекса, което публикувахте, показва, че действителните върнати редове са около 5,4 милиона (5 394 402). Това е равно на:

TotalScanRows = (MatchingRows + DiscardedRows)

(Във всеки случай според моите условия). За да получите съответстващите редове, погледнете „Действителните редове“, отчетени от оператора за свързване на сливане (може да се наложи да премахнете ТОП 100, за да получите това точно). След като знаете това, можете да получите отхвърлените редове чрез:

DiscardedRows = (TotalScanRows - MatchingRows)

И сега можете да изчислите съотношението.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как мога да дебъгвам EXCEPTION_ACCESS_VIOLATION на SQL Server 2008

  2. Как работи функцията NCHAR() в SQL Server (T-SQL)

  3. Тип данни за съхраняване на IP адрес в SQL Server

  4. SQUARE() Примери в SQL Server

  5. ODBC заявка на MS SQL Server, връщаща първите 255 знака само в PHP PDO (FreeTDS)