Niedawno rozmawiałem z innym programistą, który twierdził, że JOIN (SQL) jest bezużyteczny. Z technicznego punktu widzenia jest to prawda, ale dodał, że używanie złączeń jest mniej wydajne niż wykonywanie kilku żądań i łączenia tabel w kodzie (C # lub Java).
Dla niego przyłączenia są dla leniwych ludzi, którym nie zależy na wydajności. Czy to prawda? Czy powinniśmy unikać łączenia?
Odpowiedzi:
Nie, powinniśmy unikać programistów, którzy mają tak niewiarygodnie błędne opinie.
W wielu przypadkach łączenie bazy danych jest o kilka rzędów wielkości szybsze niż cokolwiek zrobione za pośrednictwem klienta, ponieważ pozwala uniknąć obiegów DB, a DB może użyć indeksów do wykonania sprzężenia.
Nie mogę sobie nawet wyobrazić jednego scenariusza, w którym poprawnie użyte sprzężenie byłoby wolniejsze niż równoważna operacja po stronie klienta.Edycja: Istnieją rzadkie przypadki, w których niestandardowy kod klienta może działać wydajniej niż zwykłe łączenie DB (patrz komentarz meriton). Ale to bardzo wyjątek.
źródło
Wydaje mi się, że twój kolega poradziłby sobie dobrze z bazą danych dokumentów bez sql lub magazynem wartości klucza. Które same w sobie są bardzo dobrymi narzędziami i dobrze nadają się do wielu problemów.
Jednak relacyjna baza danych jest mocno zoptymalizowana do pracy z zestawami. Istnieje wiele, wiele sposobów sprawdzania danych w oparciu o sprzężenia, które są znacznie bardziej wydajne niż wiele podróży w obie strony. Stąd bierze się wszechstronność Rdbms. Możesz osiągnąć to samo w sklepie nosql, ale często kończy się to budowaniem oddzielnej struktury dostosowanej do każdego rodzaju zapytania.
Krótko mówiąc: nie zgadzam się. W RDBMS łączenia są fundamentalne . Jeśli ich nie używasz, nie używasz ich jako RDBMS.
źródło
Cóż, w ogólnym przypadku się myli.
Bazy danych są w stanie optymalizować przy użyciu różnych metod, wspomaganych przez wskazówki optymalizatora, indeksy tabel, relacje kluczy obcych i ewentualnie inne informacje specyficzne dla dostawcy bazy danych.
źródło
Nie, nie powinieneś.
Bazy danych są specjalnie zaprojektowane do manipulowania zbiorami danych (oczywiście…). Dlatego są w tym niezwykle skuteczni. Robiąc to, co zasadniczo jest ręcznym dołączaniem do własnego kodu, próbuje przejąć rolę czegoś specjalnie zaprojektowanego do tego zadania. Szanse na to, że jego kod kiedykolwiek będzie tak wydajny, jak ten w bazie danych, są bardzo odległe.
Na marginesie, bez łączeń, jaki jest sens w korzystaniu z bazy danych? równie dobrze może po prostu używać plików tekstowych.
źródło
Jeśli „leniwy” to ludzie, którzy chcą pisać mniej kodu, to zgadzam się. Jeśli „leniwy” to ludzie, którzy chcą, aby narzędzia robiły to, w czym są dobrzy, zgadzam się. Więc jeśli on po prostu zgadza się z Larrym Wallem (co do cech dobrych programistów), to ja się z nim zgadzam.
źródło
Ummm, łączenia to sposób, w jaki relacyjne bazy danych wiążą ze sobą tabele. Nie jestem pewien, do czego zmierza.
W jaki sposób wykonanie kilku wywołań bazy danych może być bardziej wydajne niż jedno wywołanie? Dodatkowo silniki sql są zoptymalizowane do robienia tego typu rzeczy.
Może twój współpracownik jest zbyt leniwy, by nauczyć się SQL.
źródło
Tak, powinieneś.
Ze względu na wydajność powinieneś używać C ++ zamiast C #. C # jest dla leniwych.
Nie nie nie. Ze względu na wydajność powinieneś używać C zamiast C ++. C ++ jest dla leniwych.
Nie nie nie. Ze względu na wydajność należy używać assemblera zamiast C. C jest dla leniwych.
Tak, żartuję. możesz tworzyć szybsze programy bez łączeń i możesz tworzyć programy wykorzystujące mniej pamięci bez łączeń. ALE w wielu przypadkach czas tworzenia oprogramowania jest ważniejszy niż czas procesora i pamięć. Zrezygnuj z występów i ciesz się życiem. Nie trać czasu na małą wydajność. I powiedz mu: „Dlaczego nie zrobisz prostej autostrady ze swojego mieszkania do swojego biura?”
źródło
„To technicznie prawda” - podobnie baza danych SQL jest bezużyteczna: po co jej używać, skoro ten sam wynik można uzyskać, używając wielu plików CSV i skorelując je w kodzie? Heck, każda abstrakcja jest dla leniwych, wróćmy do programowania w kodzie maszynowym bezpośrednio na sprzęcie! ;)
Ponadto, jego asssertion jest nieprawdą we wszystkich, ale najbardziej zawiłe przypadkach: RDBMSs są mocno zoptymalizowany do make JOIN szybko . Systemy zarządzania relacyjnymi bazami danych, prawda?
źródło
unnecessary
raczejuseless
w poprzednim zdaniu. Mówienie, że łączenia są bezużyteczne, jest ewidentnie nieprawdziwe i nie wymaga rozważenia żadnych kwestii technicznych. W każdym razie niezrozumienie przez OP i kolegę sensu RDBMS nie jest niczym niezwykłym: stackoverflow.com/q/5575682/47550Ostatnia firma, dla której pracowałem, również nie używała sprzężeń SQL. Zamiast tego przenieśli tę pracę do warstwy aplikacji, która jest zaprojektowana do skalowania w poziomie. Uzasadnieniem tego projektu jest uniknięcie pracy w warstwie bazy danych. Zwykle wąskim gardłem staje się baza danych. Łatwiej replikować warstwę aplikacji niż bazę danych. Powody mogą być inne. Ale to jest ten, który teraz sobie przypominam.
Tak, zgadzam się, że połączenia wykonywane w warstwie aplikacji są nieefektywne w porównaniu do połączeń wykonywanych przez bazę danych. Więcej komunikacji sieciowej również.
Zwróć uwagę, że nie zajmuję twardych stanowisk w kwestii unikania złączeń SQL.
źródło
W jaki sposób bez łączenia chcesz powiązać pozycje zamówienia z zamówieniami? To jest cały punkt systemu zarządzania relacyjnymi bazami danych. Bez złączeń nie ma danych relacyjnych i równie dobrze możesz używać plików tekstowych do przetwarzania danych.
Wygląda na to, że nie rozumie tej koncepcji, więc stara się sprawiać wrażenie, że są bezużyteczne. To ten sam typ osoby, która uważa, że program Excel to aplikacja bazodanowa. Uderz go głupio i powiedz, żeby przeczytał więcej o bazach danych. Wykonywanie wielu połączeń i pobieranie danych oraz scalanie danych za pośrednictwem C # to niewłaściwy sposób robienia rzeczy.
źródło
Nie rozumiem logiki stwierdzenia „łączenia w SQL są bezużyteczne”. Czy warto filtrować i ograniczać dane przed rozpoczęciem pracy nad nimi? Jak powiedzieliście inni respondenci, właśnie to robią silniki baz danych, w tym powinny być dobre.
Być może leniwy programista trzymałby się technologii, z którymi był zaznajomiony i unikał innych możliwości z powodów nietechnicznych.
Decyzję pozostawiam Tobie.
źródło
Rozważmy przykład: tabela z rekordami faktur i powiązana tabela z rekordami pozycji faktury. Rozważ pseudokod klienta:
Jeśli masz 100 000 faktur z 10 wierszami każda, ten kod wyszuka 10 wierszy faktur z tabeli zawierającej 1 milion i zrobi to 100 000 razy. Wraz ze wzrostem rozmiaru tabeli rośnie liczba operacji wyboru i koszt każdej operacji wyboru.
Ponieważ komputery są szybkie, możesz nie zauważyć różnicy w wydajności między tymi dwoma podejściami, jeśli masz kilka tysięcy rekordów lub mniej. Ponieważ wzrost kosztów jest bardziej niż liniowy, wraz ze wzrostem liczby rekordów (powiedzmy do milionów) zaczniesz zauważać różnicę, a różnica stanie się mniej akceptowalna wraz ze wzrostem rozmiaru zestawu danych.
Jednak połączenie. użyje indeksów tabeli i połączy dwa zestawy danych. Oznacza to, że efektywnie skanujesz drugą tabelę raz, zamiast losowego dostępu do niej N razy. Jeśli zdefiniowano klucz obcy, baza danych zawiera już łącza między powiązanymi rekordami przechowywanymi wewnętrznie.
Wyobraź sobie, że robisz to sam. Masz alfabetyczną listę uczniów i notatnik z raportami wszystkich uczniów (jedna strona na zajęcia). Notatnik jest posortowany według nazwisk uczniów, w tym samym porządku co lista. Jak wolałbyś kontynuować?
Lub:
źródło
Brzmi jak klasyczny przypadek „ Mogę to lepiej napisać ”. Innymi słowy, widzi coś, co postrzega jako ból w gardle (pisząc kilka złączeń w SQL) i mówi: „Jestem pewien, że mogę napisać to lepiej i uzyskać lepszą wydajność”. Powinieneś zapytać go, czy jest a) mądrzejszy i b) bardziej wykształcony niż typowa osoba, która jest po kolana w kodzie optymalizacji Oracle lub SQL Server. Możliwe, że nie jest.
źródło
Z całą pewnością się myli. Chociaż istnieją pewne zalety manipulacji danymi w językach takich jak C # czy Java, sprzężenia są najszybsze w bazie danych ze względu na naturę samego języka SQL.
SQL prowadzi szczegółowe statystyki dotyczące danych i jeśli poprawnie utworzyłeś swoje indeksy, może bardzo szybko znaleźć jeden rekord na kilka milionów. Poza tym, dlaczego miałbyś chcieć przeciągać wszystkie swoje dane do C #, aby wykonać sprzężenie, skoro możesz to zrobić bezpośrednio na poziomie bazy danych?
Zalety korzystania z języka C # wchodzą w grę, gdy trzeba wykonać coś iteracyjnie. Jeśli musisz wykonać jakąś funkcję dla każdego wiersza, prawdopodobnie jest to szybsze w C #, w przeciwnym razie łączenie danych jest optymalizowane w bazie danych.
źródło
Powiem, że trafiłem na przypadek, w którym szybciej było rozbić zapytanie i wykonać złączenia w kodzie. Mając to na uwadze, musiałem to zrobić tylko z jedną konkretną wersją MySQL. Wszystko inne, baza danych prawdopodobnie będzie szybsza (pamiętaj, że być może będziesz musiał zoptymalizować zapytania, ale nadal będzie szybsza).
źródło
Podejrzewam, że ma ograniczony pogląd na to, do czego należy używać baz danych. Jednym ze sposobów maksymalizacji wydajności jest wczytanie całej bazy danych do pamięci. W tej sytuacji możesz uzyskać lepszą wydajność i możesz chcieć wykonać sprzężenia, jeśli pamięć jest wydajna. Jednak tak naprawdę nie jest to korzystanie z bazy danych, jako bazy danych IMHO.
źródło
MEMORY
silnik). Ponowne wdrożenie funkcjonalności bazy danych bez bazy danych jest zwykle oznaką poważnego przypadku NIH;)Nie, nie tylko połączenia są lepiej zoptymalizowane w kodzie bazy danych, który ad-hoc C # / Java; ale zwykle można zastosować kilka technik filtrowania, co zapewnia jeszcze lepszą wydajność.
źródło
Myli się, łączenia są tym, czego używają kompetentni programiści. Może istnieć kilka ograniczonych przypadków, w których proponowana przez niego metoda jest bardziej wydajna (i prawdopodobnie korzystałbym z bazy danych Documant), ale nie widzę tego, jeśli masz jakąś oszukańczą ilość danych. Na przykład weź to zapytanie:
Załóżmy, że masz 10 milionów rekordów w tabeli 1 i 1 milion rekordów w tabeli 2. Załóżmy, że 9 milionów rekordów w tabeli 1 spełnia klauzulę where. Załóżmy, że tylko 15 z nich znajduje się również w tabeli 2. Możesz uruchomić tę instrukcję sql, która po prawidłowym indeksowaniu zajmie milisekundy i zwróci 15 rekordów w sieci z tylko 1 kolumną danych. Możesz też wysłać dziesięć milionów rekordów z 2 kolumnami danych i osobno wysłać kolejny 1 milion rekordów z jedną kolumną danych przez sieć i połączyć je na serwerze internetowym.
Lub oczywiście możesz przechowywać całą zawartość bazy danych na serwerze sieciowym przez cały czas, co jest po prostu głupie, jeśli masz więcej niż trywialną ilość danych i danych, które ciągle się zmieniają. Jeśli nie potrzebujesz cech relacyjnej bazy danych, nie używaj jej. Ale jeśli to zrobisz, użyj go poprawnie.
źródło
Często słyszałem ten argument w swojej karierze programisty. Niemal za każdym razem, gdy zostało to powiedziane, osoba składająca roszczenie nie miała zbyt dużej wiedzy na temat systemów relacyjnych baz danych, ich działania i sposobu, w jaki takie systemy powinny być używane.
Tak, nieprawidłowo użyte połączenia wydają się bezużyteczne lub nawet niebezpieczne. Ale jeśli jest używany we właściwy sposób, implementacja bazy danych ma duży potencjał, aby przeprowadzić optymalizacje i „pomóc” programiście w najbardziej efektywnym uzyskaniu poprawnych wyników.
Nie zapominaj, że korzystając z narzędzia,
JOIN
możesz poinformować bazę danych o sposobie, w jaki spodziewasz się, że fragmenty danych będą ze sobą powiązane, a tym samym przekaż bazie danych więcej informacji o tym , co próbujesz zrobić, a tym samym sprawi, że będzie ona lepiej dopasowana do Twoich potrzeb.Więc odpowiedź brzmi zdecydowanie: nie,
JOINS
wcale nie są bezużyteczne!źródło
Jest to „technicznie prawdziwe” tylko w jednym przypadku, który nie jest często używany w aplikacjach (gdy wszystkie wiersze wszystkich tabel w złączeniach są zwracane przez zapytanie). W większości zapytań zwracany jest tylko ułamek wierszy każdej tabeli. Silnik bazy danych często używa indeksów w celu wyeliminowania niechcianych wierszy, czasem nawet bez odczytywania rzeczywistego wiersza, ponieważ może używać wartości przechowywanych w indeksach. Sam silnik bazy danych jest napisany w językach C, C ++ itp. I jest co najmniej tak wydajny, jak kod napisany przez programistę.
źródło
O ile poważnie nie zrozumiałem, logika tego pytania jest bardzo błędna
Jeśli jest 20 wierszy w B dla każdego A, 1000 wierszy w A oznacza 20 tys. Wierszy w B. Nie może być tylko 100 wierszy w B, chyba że istnieje wiele-wiele tabeli „AB” z 20 000 wierszami zawierającymi odwzorowanie .
Aby uzyskać wszystkie informacje o tym, które 20 ze 100 wierszy B jest mapowanych na każdy wiersz A, również tabela AB. Więc to byłoby albo:
Tak więc „JOIN” w kliencie nie dodaje żadnej wartości podczas badania danych. Nie żeby to nie był zły pomysł. Gdybym pobierał jeden obiekt z bazy danych, może bardziej sensowne byłoby rozbicie go na oddzielne zestawy wyników. W przypadku połączenia typu raportu prawie zawsze spłaszczam go w jeden.
W każdym razie powiedziałbym, że połączenie krzyżowe tej wielkości prawie nie ma sensu. To kiepski przykład.
Musisz gdzieś DOŁĄCZYĆ i właśnie w tym RDBMS są dobre. Nie chciałbym pracować z żadną małpą kodu klienta, która uważa, że może zrobić lepiej.
Refleksja:
Aby dołączyć do klienta, wymagane są trwałe obiekty, takie jak DataTables (w .net). Jeśli masz jeden spłaszczony zestaw wyników, można go zużyć za pomocą czegoś lżejszego, takiego jak DataReader. Duża ilość = dużo zasobów klienta używanych w celu uniknięcia JOIN bazy danych.
źródło