EF Core - dziwne zapytanie

0

Mam taki kod:

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:

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).
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?
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

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1