EF Core - dziwne zapytanie

EF Core - dziwne zapytanie
N0
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Gdańsk
  • Postów: 647
0

Mam taki kod:

Kopiuj
var users = await dbContext.Users
                .Where(u => u.NormalizedUserName.StartsWith(query.UserName.ToUpper()))
                .Take(query.Limit)
                .ProjectTo<UserShortInfoDto>(mapper.ConfigurationProvider)
                .ToListAsync(cancellationToken);

W debugerze widać, że zostało wygenerowane takie zapytanie:

Kopiuj
SELECT TOP(@__p_1) [u].[HasAvatar], [u].[Id], [u].[UserName]
FROM [AspNetUsers] AS [u]
WHERE ([u].[NormalizedUserName] LIKE @__ToUpper_0 + N'%' AND (LEFT([u].[NormalizedUserName], LEN(@__ToUpper_0)) = @__ToUpper_0)) OR (@__ToUpper_0 = N'')

Pytania:

  1. Dlaczego pojawia się jednocześnie LIKE i LEFT? Samo LIKE by nie wystarczyło?
  2. Dlaczego po podstawieniu jakichś danych dostaję index seek zamiast index scan, skoro w SQLu pojawia się funkcja LEFT i operator AND, który gwarantuje wykonanie się tej funkcji? Jeśli wyrzucę LIKE, to dostanę index scan (index jest na NormalizedUserName).
AF
  • Rejestracja: dni
  • Ostatnio: dni
2
  1. LIKE nie wystarczy, bo może inaczej uwzględnić różne znaki (na przykład spacje) w zależności od collation i ustawień.
  2. Nie wiem, dlaczego serwer wybrał index seek, ale osobiście też bym tak wybrał. Dlaczego wolisz index scan?
N0
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Gdańsk
  • Postów: 647
0

Nie tyle że wolę, co po prostu się dziwie, bo, o ile wiem, jeśli używam kolumny jako argument jakiejś funkcji, to wykonanie index seek jest niemożliwe (zapytanie nie jest sargable, chyba tak się na to mówi). https://stackoverflow.com/a/799616

AF
  • Rejestracja: dni
  • Ostatnio: dni
1

Nie, to tak nie działa. Jeżeli używasz funkcji na kolumnie, to często nie jest używany indeks, ale nie dlatego, że jest to fizycznie niemożliwe, tylko dlatego, że system bazy danych nie jest wystarczająco sprytny. Wszystko sprowadza się do zaklepania wyszukiwania binarnego, jako zadanie domowe możesz rozkminić, jak to zrobić, jeżeli używasz LIKE i LEFT.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.