Wydajne aktualizowanie
Dzielenie na partie
Program EF Core pomaga zminimalizować przejazdy przez automatyczne dzielenie wszystkich aktualizacji w jedną rundę. Zaleca się uwzględnić następujące elementy:
var blog = context.Blogs.Single(b => b.Url == "http://someblog.microsoft.com");
blog.Url = "http://someotherblog.microsoft.com";
context.Add(new Blog { Url = "http://newblog1.microsoft.com" });
context.Add(new Blog { Url = "http://newblog2.microsoft.com" });
context.SaveChanges();
Powyższe ładuje blog z bazy danych, zmienia adres URL, a następnie dodaje dwa nowe blogi; aby to zastosować, do bazy danych są wysyłane dwie instrukcje SQL INSERT i jedna instrukcja UPDATE. Zamiast wysyłać je pojedynczo, ponieważ są dodawane wystąpienia blogów, program EF Core śledzi te zmiany wewnętrznie i wykonuje je w jednym węźle, gdy SaveChanges jest wywoływany.
Liczba instrukcji, które są wykonywane w partiach ef w ramach pojedynczej rundy, zależy od używanego dostawcy bazy danych. Na przykład analiza wydajności wykazała, że przetwarzanie wsadowe jest ogólnie mniej wydajne dla programu SQL Server, gdy są zaangażowane mniej niż 4 instrukcje. Podobnie korzyści wynikające z dzielenia na partie po około 40 instrukcjach dla programu SQL Server, dlatego program EF Core domyślnie będzie domyślnie wykonywać maksymalnie 42 instrukcje w jednej partii i wykonywać dodatkowe instrukcje w oddzielnych rundach.
Użytkownicy mogą również dostosować te progi, aby osiągnąć potencjalnie wyższą wydajność — ale należy dokładnie przeprowadzić test porównawczy przed zmodyfikowaniem następujących wartości:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True",
o => o
.MinBatchSize(1)
.MaxBatchSize(100));
}
Użyj polecenia ExecuteUpdate i ExecuteDelete, jeśli jest to istotne
Załóżmy, że chcesz dać wszystkim pracownikom podwyżkę. Typowa implementacja tej funkcji w programie EF Core wygląda następująco:
foreach (var employee in context.Employees)
{
employee.Salary += 1000;
}
context.SaveChanges();
Chociaż jest to doskonale prawidłowy kod, przeanalizujmy to, co robi z perspektywy wydajności:
- W celu załadowania wszystkich odpowiednich pracowników jest wykonywana dwukierunkowa baza danych; Należy pamiętać, że spowoduje to przeniesienie wszystkich danych wiersza pracowników do klienta, nawet jeśli będzie potrzebne tylko wynagrodzenie.
- Śledzenie zmian platformy EF Core tworzy migawki podczas ładowania jednostek, a następnie porównuje te migawki z wystąpieniami, aby dowiedzieć się, które właściwości uległy zmianie.
- Zazwyczaj jest wykonywana druga runda bazy danych w celu zapisania wszystkich zmian (należy pamiętać, że niektórzy dostawcy baz danych podzielili zmiany na wiele pasków). Mimo że takie zachowanie przetwarzania wsadowego jest znacznie lepsze niż wykonywanie w obie strony dla każdej aktualizacji, program EF Core nadal wysyła instrukcję UPDATE dla każdego pracownika, a baza danych musi wykonać każdą instrukcję oddzielnie.
Począwszy od programu EF Core 7.0, możesz użyć ExecuteUpdate
metod i ExecuteDelete
, aby wykonać to samo znacznie wydajniej:
context.Employees.ExecuteUpdate(s => s.SetProperty(e => e.Salary, e => e.Salary + 1000));
Spowoduje to wysłanie następującej instrukcji SQL do bazy danych:
UPDATE [Employees] SET [Salary] = [Salary] + 1000;
Spowoduje to UPDATE
wykonanie całej operacji w jednym wędrze, bez ładowania ani wysyłania żadnych rzeczywistych danych do bazy danych oraz bez korzystania z maszyn śledzenia zmian ef, co nakłada dodatkowe obciążenie. Aby uzyskać więcej informacji, zobacz tematy ExecuteUpdate
oraz ExecuteDelete
.
Jeśli używasz starszej wersji programu EF Core, która nie obsługuje ExecuteUpdate
jeszcze programu i ExecuteDelete
, lub chcesz wykonać złożoną instrukcję SQL, która nie jest obsługiwana przez te metody, nadal możesz użyć zapytania SQL do wykonania operacji:
context.Database.ExecuteSql($"UPDATE [Employees] SET [Salary] = [Salary] + 1000");
Aby dowiedzieć się więcej o różnicach między elementami SaveChanges
i ExecuteUpdate
ExecuteDelete
/, zobacz stronę Przegląd na temat zapisywania danych.
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla