PORÓWNANIE WYDAJNOŚCI METOD DOSTĘPU DO BAZ SQL W ŚRODOWISKU.NET COMPARISON OF DATABASE ACCESS METHOD PERFORMANCE IN.NET FRAMEWORK



Podobne dokumenty
Architektura ADO.NET Dostawcy danych Modele dostępu do danych model połączeniowy Model bezpołączeniowy

AKADEMIA GÓRNICZO-HUTNICZA im. Stanisława Staszica w Krakowie. Wydział Geologii, Geofizyki i Ochrony Środowiska. Bazy danych 2

Politechnika Poznańska TWO

Wykład 4. Architektura ADO.NET Dostawcy danych Modele dostępu do danych model połączeniowy Model bezpołączeniowy. Bazy danych 2

Programowanie obiektowe

Blaski i cienie wyzwalaczy w relacyjnych bazach danych. Mgr inż. Andrzej Ptasznik

TEMAT ĆWICZENIA Zapoznanie z technologią LINQ

Przykłady najlepiej wykonywać od razu na bazie i eksperymentować z nimi.

Wykład 8. SQL praca z tabelami 5

PHP: bazy danych, SQL, AJAX i JSON

77. Modelowanie bazy danych rodzaje połączeń relacyjnych, pojęcie klucza obcego.

Mapowanie obiektowo-relacyjne z wykorzystaniem Hibernate

Informatyka I. Programowanie aplikacji bazodanowych w języku Java. Standard JDBC.

T-SQL dla każdego / Alison Balter. Gliwice, cop Spis treści. O autorce 11. Dedykacja 12. Podziękowania 12. Wstęp 15

Pojęcie systemu baz danych

P o d s t a w y j ę z y k a S Q L

Informatyka I. Standard JDBC Programowanie aplikacji bazodanowych w języku Java

Wprowadzenie do Doctrine ORM

SQL (ang. Structured Query Language)

Modelowanie hierarchicznych struktur w relacyjnych bazach danych

Wykład 6. SQL praca z tabelami 3

strukturalny język zapytań używany do tworzenia i modyfikowania baz danych oraz do umieszczania i pobierania danych z baz danych

Konstruowanie Baz Danych SQL UNION, INTERSECT, EXCEPT

Oracle11g: Wprowadzenie do SQL

Cel przedmiotu. Wymagania wstępne w zakresie wiedzy, umiejętności i innych kompetencji 1 Język angielski 2 Inżynieria oprogramowania

SQL Server i T-SQL w mgnieniu oka : opanuj język zapytań w 10 minut dziennie / Ben Forta. Gliwice, Spis treści

Część I Dostęp do danych oraz moŝliwości programowe (silnik bazy danych)

Bazy danych. Plan wykładu. Diagramy ER. Podstawy modeli relacyjnych. Podstawy modeli relacyjnych. Podstawy modeli relacyjnych

Microsoft SQL Server Podstawy T-SQL

koledzy, Jan, Nowak, ul. Niecała 8/23, , Wrocław, , ,

Bazy danych dla producenta mebli tapicerowanych. Bartosz Janiak Marcin Sikora Wrocław r.

Podstawy języka T-SQL : Microsoft SQL Server 2016 i Azure SQL Database / Itzik Ben-Gan. Warszawa, Spis treści

Laboratorium Technologii Informacyjnych. Projektowanie Baz Danych

Autor: Joanna Karwowska

Programowanie MSQL. show databases; - pokazanie jakie bazy danych są dostępne na koncie

Language INtegrated Query (LINQ)

Projektowanie bazy danych przykład

STWORZENIE BIBLIOTEKI SŁUŻĄCEJ DO WCZYTYWANIA

Instalacja SQL Server Express. Logowanie na stronie Microsoftu

Przestrzenne bazy danych Podstawy języka SQL

Wprowadzenie do baz danych

4 Web Forms i ASP.NET Web Forms Programowanie Web Forms Możliwości Web Forms Przetwarzanie Web Forms...152

Szpieg 2.0 Instrukcja użytkownika

Database Connectivity

PRZESTRZENNE BAZY DANYCH WYKŁAD 2

Kostki OLAP i język MDX

Systemy GIS Tworzenie zapytań w bazach danych

Projektowanie obiektowe oprogramowania Wzorce architektury aplikacji (3) Wykład 11 Repository, Unit of Work Wiktor Zychla 2016

Akademia Górniczo-Hutnicza im. Stanisława Staszica w Krakowie. dr inż. Adam Piórkowski. Jakub Osiadacz Marcin Wróbel

RELACYJNE BAZY DANYCH I ICH ZNACZENIE W SYSTEMACH INFORMACJI GEOGRAFICZNEJ

Wprowadzenie do projektowania i wykorzystania baz danych Relacje

ZAPOZNANIE SIĘ ZE SPOSOBEM PRZECHOWYWANIA

Przykładowa baza danych BIBLIOTEKA

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

Bazy danych. Wykład IV SQL - wprowadzenie. Copyrights by Arkadiusz Rzucidło 1

SQL w 24 godziny / Ryan Stephens, Arie D. Jones, Ron Plew. Warszawa, cop Spis treści

Instrukcja instalacji i obsługi programu Szpieg 3

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny technologiczny Politechnika Śląska

Bazy danych. Zenon Gniazdowski WWSI, ITE Andrzej Ptasznik WWSI

Projektowanie relacyjnych baz danych

Instytut Mechaniki i Inżynierii Obliczeniowej fb.com/groups/bazydanychmt/

LABORATORIUM 8,9: BAZA DANYCH MS-ACCESS

Język DML. Instrukcje DML w różnych implementacjach SQL są bardzo podobne. Podstawowymi instrukcjami DML są: SELECT INSERT UPDATE DELETE

Ref. 7 - Język SQL - polecenia DDL i DML

Usługi analityczne budowa kostki analitycznej Część pierwsza.

Baza danych sql. 1. Wprowadzenie. 2. Repozytaria generyczne

METODY INŻYNIERII WIEDZY ASOCJACYJNA REPREZENTACJA POWIĄZANYCH TABEL I WNIOSKOWANIE IGOR CZAJKOWSKI

JDBC w LoXiMie. Interfejs Java Database Connectivity dla systemu LoXiM. Adam Michalik 2008

PRZEWODNIK PO PRZEDMIOCIE

Język SQL, zajęcia nr 1

PHP może zostać rozszerzony o mechanizmy dostępu do różnych baz danych:

Wstęp do relacyjnych baz danych. Jan Bartoszek

Podejście obiektowe do relacyjnych baz danych Hibernate.

Instrukcja laboratoryjna cz.6

Projektowanie baz danych za pomocą narzędzi CASE

Wykład 05 Bazy danych

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny technologiczny Politechnika Śląska

Informacje wstępne Autor Zofia Kruczkiewicz Wzorce oprogramowania 4

Parametry techniczne. Testy

Programowanie w MS Visual Studio 2005 z wykorzystaniem MS SQL Server 2005

AiSD zadanie trzecie

REFERAT O PRACY DYPLOMOWEJ

Bazy danych 2. Wykład 6

SQL praca z tabelami 4. Wykład 7

Bazy danych 2. Wykład 1

KARTA PRZEDMIOTU. Programowanie aplikacji bazodanowych w języku C# D1_2

Dotacje na innowacje. Inwestujemy w waszą przyszłość.

Informatyka sem. III studia inżynierskie Transport 2018/19 LAB 2. Lab Backup bazy danych. Tworzenie kopii (backup) bazy danych

Technologia informacyjna

Wykład XII. optymalizacja w relacyjnych bazach danych

Systemy baz danych. mgr inż. Sylwia Glińska

Przykładowe sprawozdanie. Jan Pustelnik

SZKOLENIE: Administrator baz danych. Cel szkolenia

QUERY język zapytań do tworzenia raportów w AS/400

Hurtownie danych. 31 stycznia 2017

41. Zmienne lokalne muszą mieć nazwę, którą poprzedza (maksymalnie 128 znaków) oraz typ (każdy z wyjątkiem: text, ntext oraz image)

Wykład 5. SQL praca z tabelami 2

Założenia do ćwiczeń: SQL Server UWM Express Edition: \SQLEXPRESS. Zapoznaj się ze sposobami użycia narzędzia T SQL z wiersza poleceń.

Transkrypt:

PORÓWNANIE WYDAJNOŚCI METOD DOSTĘPU DO BAZ SQL W ŚRODOWISKU.NET Mirosław Kordos i Justyna Żynda Akademia Techniczno-Humanistyczna w Bielsku-Białej Streszczenie. Artykuł zawiera przegląd i analizę metod dostępu do relacyjnej bazy danych na serwerach MS SQL Server 2008R2 oraz MS SQL Server 20 CTP ze środowiska.net 4.0 oraz porównanie ich wydajności. Zaprezentowano w nim opis poszczególnych metod, omówienie aplikacji testowej oraz wyniki przeprowadzonych testów i wnioski z nich wynikające. Słowa kluczowe: bazy danych, ORM COMPARISON OF DATABASE ACCESS METHOD PERFORMANCE IN.NET FRAMEWORK Abstract. Article presents overview and analysis of MS SQL Server 2008R2 and MS SQL Server 20 CTP databases access methods in.net 4.0 framework as well as their performance comparison. Additionally, this paper contains description of individual methods, review of test application and results of conducted measurements as well as conclusions. Keywords: databases, ORM Wprowadzenie Do korzystania z najpopularniejszych relacyjnych baz danych można użyć kilku metod, których działanie nie ogranicza się tylko do przekazywania poleceń do silnika bazy lub pobierania danych. Język C# niejako wymusza pisanie oprogramowania w sposób obiektowo zorientowany, dla którego występuje zjawisko impedancji obiektowo-relacyjnej (object-relational impedance mismatch) rozwiązaniem tego problemu są metody realizujące mapowanie obiektowo-relacyjne (ORM object-relational mapping). Umożliwiają one pracę na relacyjnie składowanych danych udostępniając je jako obiekty. Korzystanie z nich pociąga za sobą wykonywanie dodatkowego kodu odpowiedzialnego za przekształcenie struktury relacyjnej na obiektową (i na odwrót) oraz za tłumaczenie zapytań definiowanych w kodzie, na przykład za pomocą LINQ, na język SQL natywny dla silników bazodanowych. Oprócz obiektowej struktury, zaletami metod realizujących ORM jest między innymi samodzielne zarządzanie przez nie połączeniami do bazy danych. Są one uważane za wygodniejsze, ale niekoniecznie równie wydajne jak metody bardziej bezpośrednie.

Porównywane metody ADO.NET ADO.NET jest częścią platformy.net. Dostarcza narzędzia umożliwiające podłączenie do bazy danych, wykonywanie komend oraz pozyskiwanie danych. ADO.NET składa się z dwóch głównych komponentów: dostawcy danych (Data Provider) i obiektów Data Set. Rysunek : Architektura ADO.NET Dostawca danych odpowiada za podłączenie do bazy danych i manipulację danymi. W skład dostawcy danych wchodzą cztery klasy. Połączenie z bazą danych nawiązuje i zamyka obiekt klasy Connection. Do wykonywania zapytań, przesyłania instrukcji i wywoływania procedur składowanych służy klasa Command. Obiekt klasy DataReader dostarcza odczytywany wierszami strumień danych. DataAdapter to klasa która umożliwia zapisanie danych do obiektu Data Set, który umożliwia przechowywanie danych bez utrzymywania połączenia z bazą. Data Set zawiera obiekty Data Table posiadają one strukturę podobną do tabel w relacyjnej bazie danych. W ADO.NET możliwe są dwa sposoby dostępu do danych: z otwartym połączeniem i odłączony. W tym pierwszym aplikacja korzysta z danych dostarczonych bezpośrednio przez dostawcę danych, natomiast w sposobie odłączonym dostawca danych przekazuje dane do obiektu Data Set. LINQ TO SQL Data Classes LINQ TO SQL jest częścią platformy.net realizującą mapowanie obiektowo-relacyjne.

Zapytania do bazy danych definiowane są jako integralna część kodu programu w języku LINQ. Podczas działania programu LINQ TO SQL tłumaczy je na kod SQL i wysyła do bazy danych, zwrócone wyniki przekształcane są na obiekty którymi można manipulować. LINQ TO SQL umożliwia także wywoływanie procedur składowanych. Źródło danych reprezentuje obiekt DataContext, poszczególne tabele - wygenerowane klasy. ADO.NET Entity Framework Podobnie jak LINQ TO SQL, Entity Framework jest narzędziem ORM udostępnia fizyczny schemat bazy danych w postaci abstrakcyjnego schematu pojęciowego, niwelując impedancję pomiędzy relacyjną bazą danych i obiektowo-zorientowanym językiem programowania. W przeciwieństwie do LINQ TO SQL, które mapuje schemat bazy danych na klasy w sposób bezpośredni, Entity Framework umożliwia stworzenie modelu danych luźno sprzężonego ze schematem bazy. Przykładowo możliwe jest mapowanie kilku tabel do pojedynczej klasy i odwrotnie. Kolejną właściwością Entity Framework, której brakuje LINQ TO SQL, jest bezpośrednia obsługa relacji wiele do wiele. Obiekt ObjectContext umożliwia wykonywanie manipulacji danymi poprzez obiekty encji. Aplikacja testowa Dla potrzeb aplikacji zaprojektowano trzy schematy baz danych. Pierwszy stanowiący uproszczony model systemu zamówień, drugi abstrakcyjny, z niewielką ilością tabel i relacji oraz trzeci analogiczny z drugim ale ze zwiększoną ilością tabel i relacji. Bazy zostały wypełnione danymi stworzonymi w sposób losowy, w oparciu o generator liczb pseudo-losowych zaimplementowany w bibliotekach systemowych.net klasę Random. Zapytania SELECT realizowane są przy użyciu klasy Data Reader (poprzez zapytanie oraz wywołanie procedury składowanej), klasy Data Set (poprzez zapytanie oraz wywołanie procedury składowanej), klas mapujących LINQ TO SQL i metody reprezentującej procedurę składowaną oraz encji Entity Framework. Zapytania INSERT wykonywane są przy pomocy klasy Data Reader (poprzez zapytanie oraz wywołanie procedury składowanej), klas mapujących LINQ TO SQL i metody reprezentującej procedurę składowaną oraz encji Entity Framework. Zapytania UPDATE wykonywane są przy pomocy klasy Data Reader (poprzez zapytanie oraz wywołanie procedury składowanej), klas mapujących LINQ TO SQL i metody reprezentującej procedurę składowaną oraz encji Entity Framework. Do pomiaru czasu wykonywania poszczególnych zapytań użyto klasy StopWatch z przestrzeni nazw System.Diagnostics. Przed każdym pomiarem tworzono obiekt klasy StopWatch, pomiar rozpoczynając wywołaniem metody Start a kończąc metodą Stop. Czas pomiaru wskazuje właściwość Elapsed. Pod uwagę brano tylko sam czas wykonywania zapytania. Czas trwania nawiązywania połączenia, tworzenia obiektów niezbędnych do wykonania komendy, generowania danych nie był

mierzony. Testy przeprowadzono na komputerze z 32 bitowym systemem Windows 7, procesorem Intel Pentium 4 3,00 GHz, dwoma dyskami ATA 70 i 20 GB. Zaprezentowane wyniki pochodzą z testów na MS SQL Server 2008 R2, wyniki testów przeprowadzonych na MS SQL Server 20 CTP były zbliżone. Analiza wyników Zapytania SELECT Zapytanie pierwsze Zapytanie pierwsze zwraca wszystkie dane z tabeli. W przypadku schematu pierwszego z tabeli DBKlienci, w drugim schemacie z tabeli DB2T oraz w trzecim z tabeli DB3T. Zapytanie w SQL dla pierwszego schematu bazy: SELECT * FROM DBKlienci; Odpowiadające mu zapytanie LINQ: List<DBKlienci> klienci = (from k in dc.dbkliencis select k).tolist(); W tym przypadku dla każdego stanu bazy DB najszybsze okazały się metody Data Reader oraz Data Reader wywołujący procedurę składowaną. Średnie geometryczne czasów ich wykonywania są do siebie bardzo zbliżone, odchylenia standardowe również są niewielkie. Trzecie w kolejności najszybszego wykonywania jest wywoływanie procedury składowanej za pomocą LINQ TO SQL. Następnie bardzo zbliżone do siebie czasami wykonywania dla większości stanów bazy danych LINQ TO SQL, Data Adapter i wywoływanie przez niego procedury składowanej. Dla większości stanów bazy danych najwolniej radziło sobie Entity Framework, ale dla 024000 wierszy w tabeli DBKlient jego miejsce zajął Data Adapter, którego średnia czasów wykonywania gwałtownie wzrosła, wzrosło również odchylenie standardowe co wskazuje na duży rozrzut czasów wykonywania przez niego zapytania. Dla bazy DB2 czasy wykonywania zapytania pierwszego są niższe, zmniejszyły się także różnice pomiędzy szybkością działania poszczególnych metod dla 64000 i 28000 wierszy różnica między szybkością działania najszybszej metody DataReader i wywoływanej przez nią procedury składowanej a pozostałymi metodami bardzo się zmniejszyła. Spadek wydajności był stały na co wskazuje brak wzrostu odchylenia standardowego. Niezmieniona w stosunku do pomiarów dla DB pozostała kolejność metod od najszybszej do najwolniejszej: metody DataAdapter + DataSet, wywoływana przez nie procedura składowana oraz LINQ TO SL uzyskały zbliżone czasy, trochę lepiej radziła sobie procedura składowana wywoływana przez LINQ TO SQL. Najgorzej wypadło Entity Framework. Różnice pomiędzy działaniem najszybszej i najwolniejszej metody wynoszą od do 25 sekund.

Czas w sekundach (średnia geometryczna) 00 0 T T_SPR OC 0, 32000 64000 28000 256000 52000 024000 Ilość wierszy w tabeli Klient Rysunek 2: Wykres czasów wykonywania pierwszego zapytania SELECT dla bazy DB 00 0 0, T T_SPROC 0,0 32000 64000 28000 256000 52000 024000 Ilość wierszy w tabeli T Rysunek 3: Wykres średnich geometrycznych czasów zapytania SELECT typu pierwszego dla bazy DB2 Dla bazy DB3 czasy wykonywania zapytania pierwszego są najwyższe. Podobnie jak w dwóch poprzednich schematach najlepiej wypadła metoda DataReader i wywoływana przez nią procedura składowana. Następną najbardziej wydajną metodą jest procedura składowana wywoływana przez LINQ TO SQL ale dla większej ilości wierszy w bazie jej miejsce zajmuje Entity Framework, który dla mniejszej ilości wierszy wypada najgorzej. LINQ TO SQL, DataAdpater z DataSet oraz procedura składowana przez niego wywoływana wypadają najgorzej dla większej ilości wierszy. Różnice między najlepszym a najgorszym wynikiem wynoszą od,9 sekundy do 203 sekund. Wraz

ze wzrostem wierszy w bazie odnotowano zdecydowany wzrost odchylenia standardowego. Ta nierównomierność w najmniejszym stopniu dotyczyła metody Data Reader oraz wywoływanej przez nią procedury składowanej. 000 00 0 0, 32000 64000 28000 256000 52000 T T_SPROC Ilość wierszy w tabeli T Rysunek 4: Wykres średnich geometrycznych czasów wykonywania pierwszego zapytania SELECT dla bazy DB3 Zapytanie drugie Drugie zapytanie łączy dwie tabele i zlicza ilość wierszy dla których istnieje powiązanie z daną wartością. Wartości są zliczane dla wierszy spełniających zdefiniowany warunek. Dla tabel z pierwszego schematu zapytanie łączy tabelę DBProdukty z tabelą DBZamowieniaPozycje i zwraca nazwy produktów których ceny jednostkowe są większe od 00 oraz ilość pozycji zamówień na których znajduje się dany produkt. W SQL: SELECT DBProdukty.nazwa, count(id_pozycja) FROM DBZamowieniaPozycje JOIN DBProdukty ON DBZamowieniaPozycje.id_produkt = DBProdukty.id_produkt WHERE DBProdukty.cena_jednostkowa > 00 GROUP BY DBProdukty.id_produkt, DBProdukty.nazwa; oraz w LINQ: var produkty = (from p in dc.dbprodukties where p.cena_jednostkowa > 00 group p by p.id_produkt into g select new { nazwa = g.select(y => y.nazwa), ilosc = g.select(x => x.dbzamowieniapozycjes.select(z => z.id_pozycja).count()) }).ToList();

Dla drugiego i trzeciego schematu tabelom DBProdukty i DBZamowieniaPozycje odpowiadają kolejno tabele DB2T i DB2T2 oraz DB3T i DB3T2. Wykonanie zapytania drugiego zajmowało więcej czasu najmniej przy wywoływaniu procedury składowanej za pomocą Data Readera na równi z użyciem Data Readera z komendą zdefiniowaną w obiekcie SqlCommand jak i wywoływaniem procedury składowanej przez LINQ TO SQL. Nieco gorzej radził sobie Data Adapter przy użyciu komendy jak i procedury, oraz Entity Framework. Tak jak przy wykonywaniu pierwszego zapytania czas wykonywania polecenia przez Data Adapter, oraz jego odchylnie standardowe, mocno wzrosły dla 02400 wierszy w tabeli. Najgorzej wypadła metoda LINQ TO SQL, której czas wykonywania zapytania ze złączeniami jest wręcz nieporównywalny z czasami innych metod. Z tego powodu też nie została ona umieszczona na wykresie. Średnia wykonywania zapytania przez LINQ TO SQL dla 32000 wierszy wynosi 437,30 sekund a dla 64000 wierszy 659,32. Dla takiej ilości wierszy tylko Entity Framework wykonał zapytanie w czasie większym niż sekunda: te czasy to odpowiednio,09 i 2,02 sekundy. Różnice pomiędzy czasami tych dwóch metod wynoszą w przybliżeniu 7 i 27 minut dla odpowiednio 32000 i 64000 wierszy. 00,00 0,00,00 T T_SPR OC 0,0 32000 64000 28000 256000 52000 024000 IIlość wierszy w tabeli DBKlient Rysunek 5: Wykres czasów wykonywania drugiego zapytania SELECT dla bazy DB Dla bazy DB2 kolejność najbardziej wydajnych metod jest taka sama jak dla bazy DB, a wykres prezentuje się bardzo podobnie. Czasy wykonywania są jednak nieco niższe niż w przypadku bazy DB. Tak samo jak na poprzednim wykresie pominięte zostały czasy wykonywania zapytania przez LINQ TO SQL, którego czasy dla 32000 i 64000 wierszy wynoszą 307 i 54 sekund dla czasów pozostałych metod mieszczących się odpowiednio w granicach 0,2 0,8 oraz,4,6.

Czas wykonywania (średnia geometryczna) 00 0 0, 32000 64000 28000 256000 52000 024000 T T_SPROC Ilość wierszy w tabeli T Rysunek 6: Wykres średnich geometrycznych czasów wykonywania zapytania SELECT typu drugiego dla bazy DB2 Dla bazy DB3 wraz ze wzrostem ilości wierszy w bazie czas wykonywania zapytania przez poszczególne metody wzrasta gwałtowniej, odnotowano również wzrost odchylenia standardowego a różnica między metodami w stosunku do czasów wykonywania zmniejsza się. Najgorzej wypada Entity Framework. Najlepiej Data Reader oraz procedura składowana wywoływana przez niego i przez LINQ TO SQL. 00 0 0, 32000 64000 28000 256000 52000 T T _SPROC Ilość wierszy w tabeli T Rysunek 7: Wykres średnich geometrycznych czasów wykonywania zapytania SELECT typu drugiego dla bazy DB3

Zapytanie trzecie Trzecie zapytanie łączy trzy tabele. Zwraca sumę wartości operacji mnożenia z powiązanych wierszy. Dla pierwszego schematu zapytanie zwraca imię klienta i sumę wartości jego zamówień obliczanych jako iloczyn ceny i ilości zakupionych produktów zapisanych w pozycjach zamówień. Zapytanie trzecie w SQL: SELECT DBKlienci.imie, sum(dbzamowieniapozycje.cena * ilosc) FROM DBKlienci JOIN DBZamowienia ON DBKlienci.id_klient=DBZamowienia.id_klient JOIN DBZamowieniaPozycje ON DBZamowienia.id_zamowienie = DBZamowieniaPozycje.id_zamowienie GROUP BY DBKlienci.id_klient, DBKlienci.imie; Odpowiadające zapytanie w LINQ: var klienci = (from k in dc.dbkliencis join z in dc.dbzamowienias on k.id_klient equals z.id_klient join zp in dc.dbzamowieniapozycjes on z.id_zamowienie equals zp.id_zamowienie group zp by k.id_klient into g select new { klient = g.select(x => x.dbzamowienia.dbklienci.imie), suma = g.sum(y => y.cena * y.ilosc) } ).ToList(); Dla drugiego i trzeciego schematu tabelom DBKlienci, DBZamowienia, DBZamowieniaPozycje odpowiadają kolejno tabele DB2T, DB2T2 i DB2T3 oraz DB3T, DB3T2 i DB3T3. Czasy wykonywania zapytania trzeciego są nieco wyższe, najszybciej wykonywały je procedura składowana wywoływana przez Data Reader, procedura wywoływana przez LINQ TO SQL i komenda Data Reader. Niewiele dłużej zapytanie wykonywał Data Adapter przy użyciu komendy i procedury składowanej. Dla 024000 wierszy zwiększyły się różnice w czasach wykonywania zapytania przez Data Adapter i średnia czasu wykonywania przez niego zapytania. Zwiększyła się również różnica w czasie wykonywania zapytania przy użyciu Entity Framework w stosunku do szybszych metod, wciąż jednak nie tak drastyczna jak czasy wykonywania zapytania przez LINQ TO SQL, dla którego dodanie kolejnego złączenia pogłębiło przepaść dzielącą je od pozostałych metod. Różnice pomiędzy wykonywaniem zapytania przez Entity Framework i LINQ TO SQL dla 32000 i 64000 wierszy wynoszą 20 i 80 minut.

Czas w sekundach (średnia geometryczna) 000,00 00,00 0,00,00 T T_SPR OC 0,0 32000 64000 28000 256000 52000 024000 Ilość wierszy w tabeli DBKlient Rysunek 8: Wykres czasów wykonywania trzeciego zapytania SELECT dla bazy DB Wyniki pomiarów dla schematu DB2 są analogiczne w stosunku do wyników dla DB. Wykres prezentuje się bardzo podobnie jednak średnie czasy wykonywania zapytania są mniejsze. Podobnie jak w przypadku DB różnica między LINQ TO SQL i pozostałymi metodami jest diametralna. 00 0 T T_SPROC 0, 32000 64000 28000 256000 52000 024000 Ilość wierszy w tabeli DB2T R ysunek 9: Wykres średnich geometrycznych czasów wykonywania zapytania SELECT typu trzeciego dla bazy DB2 Wyniki wykonania zapytania trzeciego dla DB3 są bardzo podobne do wyników zapytania drugiego dla tej samej bazy. Podobnie jak w poprzednim przypadku wraz ze wzrostem ilości wierszy w bazie odnotowano bardziej gwałtowny przyrost czasów wykonywania zapytania dla

wszystkich metod oraz zmniejszenie różnicy pomiędzy poszczególnymi czasami w stosunku do czasu wykonywania. Wraz ze wzrostem ilości wierszy rośnie również odchylenie standardowe. Dla większości przypadków najlepiej wypada metoda Data Reader oraz procedura składowana wywoływana przez niego i LINQ TO SQL. 000 00 0 0, 32000 64000 28000 256000 52000 T T_SPROC Ilość wierszy w tabeli DB3T Rysunek 0: Wykres średnich geometrycznych czasów wykonywania zapytania SELECT typu trzeciego dla bazy DB3 Zapytania INSERT Podczas wykonywania zapytania INSERT do tabeli zapisywane są nowe wiersze z losowo utworzonymi wartościami. Zapytanie wykonywane jest dla różnej ilości jednorazowo zapisywanych wierszy. Dla schematu pierwszego dane dodawane są do tabeli DBKlienci, zapytanie w SQL wygląda następująco: INSERT INTO [DBKlienci] ([mail], [imie], [nazwisko], [miejscowosc], [ulica], [numer_lokalu],[numer_telefonu]) VALUES (@mail, @imie, @nazwisko, @miejscowosc, @ulica, @numerlokalu, @numertelefonu); W schemacie drugim i trzecim dane są dodawane odpowiednio do tabeli DB2T oraz DB3T. Po wykonaniu zapytania wiersze są usuwane aby następne zapytania były wykonywane na bazie w identycznym stanie. Zapytania INSERT wszystkie metody wykonywały w dość zbliżonym czasie, wzrastającym wraz z ilością dodawanych do bazy wierszy. Czasy wykonywania tworzą dwie grupy metod których średnie czasy wykonania niewiele się różnią. W grupie szybszej znalazły się metody Command i wywołanie przez nią procedury składowanej oraz Entity Framework. W grupie wolniejszej znalazło się LINQ TO SQL i wywoływana przez nią procedura składowana. Różnice w czasach pomiędzy tymi dwoma grupami wynoszą od do 20 sekund.

Czas w sekundach (średnia geometryczna) 00 0 COMMAND COMMAND_SPROC 0, 000 2000 4000 8000 6000 32000 Ilość dodawanych wierszy Rysunek : Wykres czasów wykonywania zapytania INSERT dla 64000 wierszy w tabeli DBKlient Zwiększenie ilości wierszy w bazie danych nie wpłynęło znacząco na czas wykonywania zapytań INSERT. 00 0 COMMAND COMMAND_SPROC 0, 000 2000 4000 8000 6000 32000 Ilość dodawanych wierszy Rysunek 2: Wykres czasów wykonywania zapytania INSERT dla 28000 wierszy w tabeli DBKlient Wykres czasów dodawania wierszy do tabeli w bazie DB2 jest bardzo podobny do wykresu dla bazy DB. Czasy wykonywania zapytania przez poszczególne metody plasują się takiej samej kolejności. Średnie czasów są jednak nieco mniejsze.

Czas w sekundach (średnia geometryczna) 00 0 COMMAND COMMAND_SPROC 0, 000 2000 4000 8000 6000 32000 Ilość dodawanych wierszy Rysunek 3: Wykres średnich geometrycznych czasów wykonywania zapytania INSERT dla 64000 wierszy w tabeli DB2T Podobnie do czasów wykonywania zapytania INSERT dla bazy DB2 prezentują się wyniki dla bazy DB3. Zwiększyła się różnica między czasami wykonania zapytania przez Command oraz wywołaną przez niego procedurę i Entity Framework. Czasy wykonania zwiększyły się dla wszystkich metod. Spadek wydajności procedury wywołanej przez LINQ TO SQL jest związany ze wzrostem odchylenia standardowego. 00 0 COMMAND COMMAND_SPROC 0, 000 2000 4000 8000 6000 32000 Ilość dodanych wierszy Rysunek 4: Wykres średnich geometrycznych czasów wykonywania zapytania INSERT dla 64000 wierszy w tabeli DB3T

Zapytania UPDATE Podczas wykonywania zapytania UPDATE z tabeli losowo wybrany zostaje wiersz którego wartości zostaną zaktualizowane przez nowe, otrzymane losowo. Zapytania wykonywane są dla różnej ilości jednorazowo aktualizowanych wierszy. W pierwszym schemacie aktualizowane są dane w tabeli DBProdukty, w języku SQL zapytanie przedstawia się następująco: UPDATE [DBProdukty] SET [cena_jednostkowa] = @cena_jednostkowa,[nazwa] = @nazwa,[opis] = @opis WHERE id_produkt = @id_produkt; W schemacie drugim i trzecim aktualizowane są odpowiednio tabele DB2T i DB3T. Wraz ze wzrostem ilości wierszy w bazie, wzrost czasów wykonywania zapytania UPDATE właściwy dla wzrostu ilości aktualizowanych wierszy nie jest stały dla metod Command, wywoływania przez Command procedury składowanej oraz wywoływania procedury składowanej przez LINQ TO SQL. Dla każdej ilości aktualizowanych wierszy metody te zajmują różne pozycje na liście najlepszych czasów. Jedynie dwie skrajne pozycje są zajmowane przez te same metody w większości przypadków. Najlepsze okazało się Entity Framework, wzrost czasu wykonywania przez nie zapytania wraz ze wzrostem ilości aktualizowanych danych jest stabilny. Tak samo jak w przypadku najgorzej wypadającej metody LINQ TO SQL. Różnica między najgorszą i najlepszą metodą wynosi od 2 do 68 sekund. 00 0 COMMAND COMMAND_SPROC 0, 000 2000 4000 8000 6000 32000 Ilość aktualizowanych wierszy Rysunek 5: Wykres czasów wykonywania zapytania UPDATE dla 64000 wierszy w tabeli DBProdukt

Czas w sekundach (średnia geometryczna) 00 0 COMMAND COMMAND_SPROC 0, 000 2000 4000 8000 6000 32000 Ilość aktualizowanych wierszy Rysunek 6: Wykres czasów wykonywania zapytania UPDATE dla 28000 wierszy w tabeli DBProdukt Czasy wykonywania zapytania UPDATE dla bazy DB2 są większe niż dla bazy DB, ale kolejność wyników dla poszczególnych metod jest podobna. Najlepiej wypadają metody Command, wywoływana przez nią procedura oraz Entity Framework. Najgorzej LINQ TO SQL. Różnice pomiędzy metodami wynoszą od 3,5 do 44 sekund. 00 0 COMMAND COMMAND_SPROC 0, 000 2000 4000 8000 6000 32000 Ilość aktualizowanych wierszy Rysunek 7: Wykres średnich geometrycznych czasów wykonywania zapytania UPDATE dla 64000 wierszy w tabeli DB2T

Podobnie jak w przypadku dwóch poprzednich schematów zapytanie UPDATE dla bazy DB3 najszybciej wykonują metody Command, wywoływana przez nią procedura składowana oraz Entity Framework. Najwolniej LINQ TO SQL. Średnie czasy dla wszystkich metod są najwyższe. 000 00 0 COMMAND COMMAND_SPROC 0, 000 2000 4000 8000 6000 32000 Ilość aktualizowanych wierszy Rysunek 8: Wykres średnich geometrycznych czasów wykonywania zapytania UPDATE dla 64000 wierszy w tabeli DB3T Podsumowanie W większości przeprowadzonych testów metody ORM osiągały gorszą wydajność niż metody bezpośrednie. Najgorzej wypadło LINQ TO SQL, które w wielu sytuacjach znacznie odstawało od reszty metod. Jego wydajność znacząco pogarszały bardziej skomplikowane zapytania oraz większa ilość danych. Wywoływanie przez LINQ TO SQL procedur składowanych może stanowić rozwiązanie problemu bardzo kiepskiej wydajności dla rozbudowanych zapytań. LINQ TO SQL to proste narzędzie które dobrze sprawdzi się dla niewielkich aplikacji korzystających z małych ilości danych. Przy użyciu LINQ TO SQL warto używać procedur składowanych. Entity Framework dla zapytań SELECT i INSERT nie wypadało najlepiej, ale jego wydajność nie odbiegała znacząco od innych metod. Natomiast dla zapytań UPDATE Entity Framework znajdował się w czołówce najlepszych metod. Wraz ze wzrostem skomplikowania zapytania oraz ilości danych jego wydajność nie spadała drastycznie. To narzędzie o sporych możliwościach, które może konkurować z metodami bezpośrednimi. Data Adapter i Data Set ze względu na możliwość korzystania z danych bez konieczności utrzymywania połączenia z bazą najlepiej sprawdzi się w aplikacji korzystającej z rzadko zmieniających się danych. Wydajność tej metody jest gorsza od Data Reader'a, ale w większości przypadków lepsza od metod ORM. W większości testów najbardziej wydajną metodą okazał się Data Reader i Command oraz wywoływanie przez nie procedury składowanej. Nie dostarczają one takich udogodnień jak metody ORM, ale zapewniają najlepszą wydajność.

References. Paul Nielsen, Uttam Parui and Mike White, Microsoft SQL Server 2008 Bible, Wiley, 2009 2. Ray Rankins, Paul T. Bertucci, Chris Gallelli and Alex T. Silverstein, Microsoft SQL Server 2008 R2 Unleashed, Sams Publishing, 200