Dlaczego połączenia są złe, jeśli chodzi o skalowalność?


94

Dlaczego połączenia są złe lub „wolne”. Wiem, że słyszałem to więcej niż raz. Znalazłem ten cytat

Problem polega na tym, że łączenia są stosunkowo wolne, szczególnie w przypadku bardzo dużych zestawów danych, a jeśli są wolne, Twoja witryna działa wolno. Usunięcie wszystkich tych oddzielnych fragmentów informacji z dysku i ponowne złożenie ich w całość zajmuje dużo czasu.

źródło

Zawsze myślałem, że są szybcy, zwłaszcza patrząc na PK. Dlaczego są „powolni”?

sql  join 

Odpowiedzi:


100

Skalowalność polega na przetwarzaniu wstępnym (buforowaniu), rozkładaniu lub ograniczaniu powtarzającej się pracy do podstawowych elementów, aby zminimalizować wykorzystanie zasobów na jednostkę pracy. Aby dobrze skalować, nie robisz niczego, czego nie potrzebujesz, a rzeczy, które faktycznie robisz, robisz tak wydajnie, jak to tylko możliwe.

W tym kontekście, oczywiście, łączenie dwóch oddzielnych źródeł danych jest stosunkowo wolne, przynajmniej w porównaniu z nie dołączaniem do nich, ponieważ jest to praca, którą musisz wykonać na żywo w miejscu, w którym użytkownik o to poprosi.

Pamiętaj jednak, że alternatywą nie jest już posiadanie w ogóle dwóch oddzielnych części danych; musisz umieścić dwa różne punkty danych w tym samym rekordzie. Nie możesz łączyć dwóch różnych danych gdzieś bez konsekwencji, więc upewnij się, że rozumiesz kompromis.

Dobra wiadomość jest taka, że ​​nowoczesne relacyjne bazy danych są dobre w połączeniach. Naprawdę nie powinieneś myśleć o złączeniach jako wolnych, z dobrą bazą danych używaną dobrze. Istnieje szereg skalowalności przyjaznych sposobów, aby surowo łączy i uczynić je znacznie szybciej:

  • Łączenie na podstawie klucza zastępczego (kolumny autonumeru / tożsamości) zamiast klucza naturalnego. Oznacza to mniejsze (a zatem szybsze) porównania podczas operacji łączenia
  • Indeksy
  • Widoki zmaterializowane / zindeksowane (pomyśl o tym jako o wstępnie obliczonym złączeniu lub zarządzanej denormalizacji)
  • Obliczone kolumny. Możesz użyć tego do haszowania lub w inny sposób wstępnie obliczać kolumny kluczy złączenia, tak że to, co byłoby skomplikowanym porównaniem dla złączenia, jest teraz znacznie mniejsze i potencjalnie wstępnie zindeksowane.
  • Partycje tabelaryczne (pomaga w przypadku dużych zestawów danych, rozkładając obciążenie na wiele dysków lub ograniczając to, co mogło być skanowaniem tabeli do skanowania partycji)
  • OLAP (wstępnie oblicza wyniki niektórych rodzajów zapytań / złączeń. To nie do końca prawda, ale można to potraktować jako ogólną denormalizację)
  • Replikacja, grupy dostępności, wysyłanie dzienników lub inne mechanizmy umożliwiające wielu serwerom odpowiadanie na zapytania dotyczące odczytu dla tej samej bazy danych, a tym samym skalowanie obciążenia pracą na kilka serwerów.
  • Użycie warstwy buforującej, takiej jak Redis, aby uniknąć ponownego uruchamiania zapytań, które wymagają skomplikowanych sprzężeń.

Powiedziałbym nawet, że głównym powodem istnienia relacyjnych baz danych jest umożliwienie wydajnego łączenia się * . Z pewnością nie chodzi tylko o przechowywanie ustrukturyzowanych danych (możesz to zrobić za pomocą płaskich konstrukcji plików, takich jak csv lub xml). Kilka opcji, które wymieniłem, pozwoli ci nawet całkowicie zbudować połączenie z wyprzedzeniem, więc wyniki są już zrobione przed wysłaniem zapytania - tak jakbyś zdenormalizował dane (wprawdzie kosztem wolniejszych operacji zapisu).

Jeśli masz powolne sprzężenie, prawdopodobnie nie używasz poprawnie bazy danych.

De-normalizacja powinna być przeprowadzona tylko wtedy, gdy zawiodły te inne techniki. Jedynym sposobem, w jaki możesz naprawdę ocenić „porażkę”, jest wyznaczenie znaczących celów wydajnościowych i ich porównanie. Jeśli nie mierzyłeś, jest za wcześnie, aby nawet pomyśleć o denormalizacji.

* Oznacza to, że istnieją jako jednostki odrębne od zwykłych zbiorów tabel. Dodatkowym powodem prawdziwego rdbms jest bezpieczny, jednoczesny dostęp.


14
Indeksy powinny prawdopodobnie znajdować się na górze listy. Wielu programistów ( kaszlących ) wydaje się zapomnieć o nich podczas testowania na małym zestawie danych, a następnie rzuca bazę danych na kolana w produkcji. Widziałem zapytania, które były uruchamiane 100 000 razy szybciej po prostu przez dodanie indeksów. I to są dowolne indeksy bez przeprowadzania nawet dogłębnej analizy danych w celu określenia najlepszego połączenia dla dopasowania przedrostka z lewej strony.
Duncan

Myślę, że kolejność jest właściwa - po prostu większość programistów już wykonuje pierwszy element, więc indeksy są pierwszym elementem, w którym będą musieli wprowadzić zmiany.
Joel Coehoorn

W trzecim elemencie wspominasz o „Zmaterializowanych / zindeksowanych widokach”. Mówisz o zwykłych widokach SQL, czy o czymś innym?
slolife

Zwykłe widoki sql @slolife są jak uruchamianie dodatkowego zapytania w tle w locie, gdy używasz zapytania, które odwołuje się do widoku. Ale możesz także powiedzieć serwerowi sql, aby „zmaterializował” niektóre widoki. Gdy to zrobisz, serwer sql zachowa dodatkową kopię danych widoku, tak jak zwykła tabela, tak że kiedy odwołujesz się do widoku w zapytaniu, nie musi już uruchamiać tego zapytania w tle, ponieważ dane już tam są . Możesz również umieścić w widoku inne indeksy niż tabela źródłowa, aby dodatkowo pomóc Ci dostroić wydajność.
Joel Coehoorn

Dzięki Joel. Muszę się temu przyjrzeć.
slolife

29

Łączenia mogą być wolniejsze niż unikanie ich poprzez denormalizację, ale jeśli są używane poprawnie (łączenie na kolumnach z odpowiednimi indeksami i tak dalej), nie są z natury powolne .

De-normalizacja to jedna z wielu technik optymalizacji, które można rozważyć, jeśli dobrze zaprojektowany schemat bazy danych wykazuje problemy z wydajnością.


2
... z wyjątkiem MySQL, który wydaje się mieć problemy z wydajnością przy dużej liczbie złączeń, niezależnie od wyglądu indeksów. A przynajmniej tak było w przeszłości.
Powerlord

2
Chodzi o to, że jeśli istnieją znane problemy z konkretnym DBMS (a może nawet wersją), to ta rada może mieć sens, ale jako rada ogólna jest dość myląca, jeśli używasz relacyjnej bazy danych. To powiedziawszy, nierelacyjne mechanizmy przechowywania stają się coraz bardziej popularne, przykładami są SimpleDB i CouchDB firmy Amazon ( couchdb.apache.org ). Jeśli lepiej przysłuży się pozostawienie modelu relacyjnego za sobą, prawdopodobnie powinieneś zostawić produkty zoptymalizowane pod kątem również z tyłu i poszukać innych narzędzi.
Tendayi Mawushe

13

artykuł mówi, że są powolne w porównaniu z brakiem połączeń. można to osiągnąć poprzez denormalizację. więc istnieje kompromis między szybkością a normalizacją. nie zapomnij też o przedwczesnej optymalizacji :)


nawet to nie jest trudna reguła, jeśli dołączysz do tabeli, mysql może użyć indeksu do wykonania tego łączenia - to złączenie indeksu może usunąć wiele wierszy i inny indeks dla dowolnej klauzuli where w tabelach. Jeśli nie dołączysz, mysql będzie zazwyczaj używał tylko jednego indeksu (który może nie być najbardziej efektywny), niezależnie od tego, w jaki sposób zostanie utworzona klauzula where.
leeeroy,

12

Po pierwsze, racją bytu (powodem istnienia) relacyjnej bazy danych jest możliwość modelowania relacji między podmiotami. Połączenia to po prostu mechanizmy, dzięki którym przechodzimy przez te relacje. Z pewnością mają one symboliczny koszt, ale bez łączeń naprawdę nie ma powodu, aby mieć relacyjną bazę danych.

W świecie akademickim uczymy się o różnych formach normalnych (1., 2., 3., Boyce-Codd, itp.), Oraz o różnych typach kluczy (podstawowych, obcych, alternatywnych, unikalnych itp.) te rzeczy pasują do siebie, aby zaprojektować bazę danych. Uczymy się podstaw SQL, a także manipulowania strukturą i danymi (DDL i DML).

W świecie korporacji wiele konstruktów akademickich okazuje się być znacznie mniej wykonalnych, niż sądzono. Doskonałym przykładem jest pojęcie klucza podstawowego. Z naukowego punktu widzenia to właśnie ten atrybut (lub zbiór atrybutów) jednoznacznie identyfikuje jeden wiersz w tabeli. Tak więc w wielu dziedzinach problemowych właściwy akademicki klucz główny jest złożeniem 3 lub 4 atrybutów. Jednak prawie wszyscy we współczesnym świecie korporacji używają automatycznie generowanej, sekwencyjnej liczby całkowitej jako klucza podstawowego tabeli. Czemu? Dwa powody. Po pierwsze, sprawia, że ​​model jest znacznie czystszy podczas migracji elementów FK w różne miejsca. Drugim i najbardziej związanym z tym pytaniem jest to, że pobieranie danych przez łączenia jest szybsze i bardziej wydajne na pojedynczej liczbie całkowitej niż na 4 kolumnach varchar (jak już wspomniało kilka osób).

Zagłębmy się teraz nieco głębiej w dwa specyficzne podtypy rzeczywistych baz danych. Pierwszy typ to baza transakcyjna. To podstawa wielu aplikacji do handlu elektronicznego lub zarządzania treścią, napędzających nowoczesne witryny. Z bazą danych transakcji mocno optymalizujesz w kierunku „przepustowości transakcji”. Większość aplikacji handlowych lub związanych z treścią musi równoważyć wydajność zapytań (z niektórych tabel) z wydajnością wstawiania (w innych tabelach), chociaż każda aplikacja będzie miała własne, unikalne problemy biznesowe do rozwiązania.

Drugi typ rzeczywistej bazy danych to baza danych raportowania. Są one wykorzystywane prawie wyłącznie do agregowania danych biznesowych i generowania sensownych raportów biznesowych. Zazwyczaj mają inny kształt niż bazy danych transakcji, w których generowane są dane, i są wysoce zoptymalizowane pod kątem szybkości ładowania danych zbiorczych (ETL) i wydajności zapytań z dużymi lub złożonymi zestawami danych.

W każdym przypadku programista lub administrator danych musi dokładnie zrównoważyć zarówno funkcjonalność, jak i krzywe wydajności, a po obu stronach równania istnieje wiele sztuczek zwiększających wydajność. W Oracle można wykonać tak zwany „plan wyjaśniania”, dzięki czemu można dokładnie zobaczyć, w jaki sposób zapytanie jest analizowane i wykonywane. Chcesz zmaksymalizować prawidłowe wykorzystanie indeksów przez bazę danych. Naprawdę nieprzyjemnym nie-nie jest umieszczenie funkcji w klauzuli where zapytania. Kiedykolwiek to zrobisz, gwarantujesz, że Oracle nie użyje żadnych indeksów w tej konkretnej kolumnie i prawdopodobnie zobaczysz pełne lub częściowe skanowanie tabeli w planie wyjaśniania. To tylko jeden konkretny przykład tego, jak można napisać zapytanie, które kończy się powolnością i nie ma nic wspólnego z łączeniami.

A skoro mówimy o skanach tabel, oczywiście wpływają one na szybkość zapytań proporcjonalnie do rozmiaru tabeli. Pełne skanowanie 100 wierszy tabeli nie jest nawet zauważalne. Uruchom to samo zapytanie na tabeli zawierającej 100 milionów wierszy, a po powrocie musisz wrócić w przyszłym tygodniu.

Porozmawiajmy przez chwilę o normalizacji. To kolejny bardzo pozytywny temat akademicki, który może być nadmiernie zestresowany. W większości przypadków, gdy mówimy o normalizacji, tak naprawdę mamy na myśli eliminację zduplikowanych danych poprzez umieszczenie ich we własnej tabeli i migrację FK. Ludzie zwykle pomijają całą zależność opisaną przez 2NF i 3NF. A jednak w skrajnym przypadku z pewnością możliwe jest posiadanie doskonałej bazy danych BCNF, która jest ogromna i kompletna bestia do pisania kodu, ponieważ jest tak znormalizowana.

Więc gdzie balansujemy? Nie ma jednej najlepszej odpowiedzi. Wszystkie lepsze odpowiedzi są zwykle kompromisem między łatwością utrzymania struktury, łatwością obsługi danych i łatwością tworzenia / konserwacji kodu. Ogólnie rzecz biorąc, im mniej duplikatów danych, tym lepiej.

Dlaczego więc łączenia są czasami powolne? Czasami jest to zły projekt relacji. Czasami jest to nieefektywne indeksowanie. Czasami jest to problem z ilością danych. Czasami jest to okropnie napisane zapytanie.

Przepraszam za tak rozwlekłą odpowiedź, ale czułem się zmuszony do podania bardziej mięsistego kontekstu wokół moich komentarzy, zamiast po prostu wyrzucać 4-punktową odpowiedź.


10

Osoby z bazami danych o wielkości terabajtów nadal używają złączeń, jeśli mogą zmusić je do pracy pod względem wydajności, to Ty też możesz.

Istnieje wiele powodów, dla których nie należy denomalizować. Po pierwsze, szybkość wybierania zapytań nie jest jedynym, ani nawet głównym problemem związanym z bazami danych. Integralność danych jest najważniejsza. Jeśli zdenormalizujesz, musisz zastosować techniki, które pozwolą zachować denormalizację danych, gdy zmieniają się dane nadrzędne. Więc przypuśćmy, że zaczynasz przechowywać nazwę klienta we wszystkich tabelach, zamiast łączyć się z tabelą klienta w client_Id. Teraz, gdy zmieni się nazwa klienta (100% szansa, że ​​niektóre nazwy klientów zmienią się w czasie), teraz musisz zaktualizować wszystkie rekordy podrzędne, aby odzwierciedlić tę zmianę. Jeśli zrobisz to za pomocą kaskadowej aktualizacji i masz milion rekordów podrzędnych, jak myślisz, jak szybko to nastąpi i ilu użytkowników będzie cierpieć z powodu problemów z blokowaniem i opóźnień w ich pracy, gdy to nastąpi? Ponadto większość ludzi denormalizuje się, ponieważ „

Denormalizacja to złożony proces, który wymaga dogłębnego zrozumienia wydajności i integralności bazy danych, jeśli ma być wykonany poprawnie. Nie próbuj denormalizować, jeśli nie masz takiej wiedzy na temat personelu.

Połączenia są dość szybkie, jeśli robisz kilka rzeczy. Najpierw użyj klucza suggorgate, złączenie int jest prawie zawsze najszybszym złączeniem. Po drugie zawsze indeksuj klucz obcy. Użyj tabel pochodnych lub warunków łączenia, aby utworzyć mniejszy zestaw danych do filtrowania. Jeśli masz dużą, bardzo złożoną bazę danych, zatrudnij profesjonalną osobę z doświadczeniem w dzieleniu na partycje i zarządzaniu dużymi bazami danych. Istnieje wiele technik poprawiających wydajność bez usuwania połączeń.

Jeśli potrzebujesz tylko możliwości zapytań, to tak, możesz zaprojektować magazyn danych, który można zdenormalizować i który jest wypełniany za pomocą narzędzia ETL (zoptymalizowanego pod kątem szybkości), a nie wprowadzania danych użytkownika.


8

Połączenia są powolne, jeśli

  • dane są nieprawidłowo indeksowane
  • wyniki słabo filtrowane
  • dołączanie zapytania źle napisane
  • zbiory danych są bardzo duże i złożone

Tak więc, to prawda, im większe są twoje dane, tym więcej przetwarzania potrzebujesz do zapytania, ale sprawdzenie i praca nad pierwszymi trzema opcjami powyżej często daje świetne wyniki.

Twoje źródło daje możliwość denormalizacji. Jest to w porządku tylko wtedy, gdy wyczerpałeś lepsze alternatywy.


7

Łączenia mogą być powolne, jeśli trzeba przeskanować duże porcje rekordów z każdej strony.

Lubię to:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id

Nawet jeśli indeks jest zdefiniowany account_customer, wszystkie rekordy z tego ostatniego nadal wymagają przeskanowania.

W przypadku listy zapytań przyzwoite optymalizatory prawdopodobnie nawet nie rozważą ścieżki dostępu do indeksu, wykonując zamiast tego a HASH JOINlub MERGE JOINa.

Zauważ, że w przypadku takiego zapytania:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id
WHERE   customer_last_name = 'Stellphlug'

łączenie najprawdopodobniej będzie szybkie: najpierw indeks włączony customer_last_namezostanie użyty do odfiltrowania wszystkich Stellphlugów (których oczywiście nie ma zbyt wielu), a następnie skan indeksu account_customerzostanie wykonany dla każdego Stellphluga w celu znalezienia jego transakcji.

Pomimo faktu, że mogą to być miliardy rekordów accountsi customers, tylko nieliczne będą wymagały zeskanowania.


ale trudno tego uniknąć. zaprojektuj swoją aplikację tak, aby tego rodzaju zapytania nie były wykonywane zbyt często.
Andrey

1
Jeśli indeks jest zdefiniowany w accounts(account_customer)większości systemów RDBMS, będzie on używał tego indeksu do ustalenia, które dokładnie wiersze customersbazy danych wymagają przeskanowania.
jemfinch

tak, ale i tak nie jest to tania operacja. możesz przechowywać sumę w jakimś polu i aktualizować w każdej transakcji.
Andrey,

@jemfinch: nie, nie będą. Wymagałoby to przeskanowania całego indeksu tylko po to, by odfiltrować klientów, a następnie skanowania indeksu klienta w zagnieżdżonej pętli. A HASH JOINbyłby znacznie szybszy, więc będzie to, co będzie używane z wyjątkiem wszystkich głównych baz danych, z wyjątkiem tych MySQL, które będą po prostu powodować customerswprowadzanie w zagnieżdżonej pętli (ponieważ jest mniejszy)
Quassnoi

4

Joins are fast.Łączenia należy traktować jako standardową praktykę z odpowiednio znormalizowanym schematem bazy danych. Połączenia umożliwiają łączenie różnych grup danych w znaczący sposób. Nie bój się połączenia.

Zastrzeżenie polega na tym, że musisz zrozumieć normalizację, łączenie i prawidłowe użycie indeksów.

Uważaj na przedwczesną optymalizację, ponieważ najważniejszym niepowodzeniem wszystkich projektów deweloperskich jest dotrzymanie terminu. Po ukończeniu projektu i zrozumieniu kompromisów możesz złamać zasady, jeśli możesz to uzasadnić.

Prawdą jest, że wydajność łączenia spada nieliniowo wraz ze wzrostem rozmiaru zbioru danych. Dlatego nie skaluje się tak dobrze, jak zapytania w pojedynczej tabeli, ale nadal skaluje.

Prawdą jest również, że ptak leci szybciej bez skrzydeł, ale tylko prosto w dół.


3

Łączenia wymagają dodatkowego przetwarzania, ponieważ muszą przeszukiwać więcej plików i więcej indeksów, aby „połączyć” dane. Jednak „bardzo duże zbiory danych” są względne. Jaka jest definicja dużego? W przypadku JOIN, myślę, że jest to odniesienie do dużego zbioru wyników, a nie do ogólnego zbioru danych.

Większość baz danych może bardzo szybko przetworzyć zapytanie, które wybiera 5 rekordów z tabeli podstawowej i łączy 5 rekordów z powiązanej tabeli dla każdego rekordu (zakładając, że istnieją prawidłowe indeksy). Każda z tych tabel może mieć setki milionów rekordów, a nawet miliardy.

Gdy zestaw wyników zacznie się powiększać, sytuacja ulegnie spowolnieniu. Posługując się tym samym przykładem, jeśli wynik z tabeli podstawowej wynosi 100 tys. Rekordów, trzeba będzie znaleźć 500 tys. „Połączonych” rekordów. Po prostu wyciągam tyle danych z bazy danych z dodatkowymi opóźnieniami.

Nie unikaj POŁĄCZEŃ, po prostu wiedz, że może zajść potrzeba optymalizacji / denormalizacji, gdy zbiory danych staną się „bardzo duże”.


3

Również z cytowanego artykułu:

Wiele witryn o ogromnej skali z miliardami rekordów, petabajtami danych, wieloma tysiącami jednoczesnych użytkowników i milionami zapytań dziennie wykorzystuje schemat dzielenia na fragmenty, a niektóre nawet opowiadają się za denormalizacją jako najlepszą strategią projektowania warstwy danych.

i

A jeśli nie jesteś naprawdę dużą witryną, prawdopodobnie nie musisz się martwić o ten poziom złożoności.

i

Jest to bardziej podatne na błędy niż posiadanie bazy danych wykonującej całą tę pracę, ale możesz skalować poza to, co mogą obsłużyć nawet najwyższe bazy danych.

Artykuł omawia mega-strony, takie jak Ebay. Na tym poziomie użytkowania prawdopodobnie będziesz musiał rozważyć coś innego niż zwykłe zarządzanie relacyjnymi bazami danych. Jednak w „normalnym” toku działalności (aplikacje z tysiącami użytkowników i milionami rekordów) te droższe, bardziej podatne na błędy podejścia są przesadą.


2

Połączenia są uważane za siłę przeciwstawną do skalowalności, ponieważ zwykle stanowią wąskie gardło i nie można ich łatwo dystrybuować ani równolegle.


Nie jestem pewien, czy to prawda. Wiem, że Teradata z pewnością jest w stanie rozprowadzać sprzężenia wśród Amps. Oczywiście niektóre typy połączeń mogą być trudniejsze / trudniejsze niż inne.
Cade Roux,

indeksy mogą być partycjonowane w RDBMS od mysql do oracle. AFAIK, który skaluje (jest dystrybuowany i może być równoległy).
Bez powodu

2

Prawidłowo zaprojektowane tabele zawierające odpowiednie wskazania i poprawnie napisane zapytania nie zawsze są powolne. Gdziekolwiek to słyszałeś:

Dlaczego połączenia są złe lub „wolne”

nie ma pojęcia, o czym mówią !!! Większość połączeń będzie bardzo szybkich. Jeśli musisz połączyć wiele wierszy jednocześnie, możesz przyjąć trafienie w porównaniu ze zdenormalizowaną tabelą, ale to wraca do Prawidłowo zaprojektowanych tabel, wiedz, kiedy denormalizować, a kiedy nie. w ciężkim systemie raportowania podziel dane w zdenormalizowanych tabelach na potrzeby raportów, a nawet utwórz hurtownię danych. W ciężkim systemie transakcyjnym normalizuj tabele.


1

Ilość generowanych danych tymczasowych może być ogromna w przypadku łączenia.

Na przykład jedna baza danych tutaj w pracy miała ogólną funkcję wyszukiwania, w której wszystkie pola były opcjonalne. Procedura wyszukiwania połączyła się na każdym stole przed rozpoczęciem wyszukiwania. Na początku działało to dobrze. Ale teraz, gdy główna tabela ma ponad 10 milionów wierszy ... nie tak bardzo. Wyszukiwanie trwa teraz co najmniej 30 minut.

Otrzymałem zadanie optymalizacji procedury składowanej wyszukiwania.

Pierwszą rzeczą, jaką zrobiłem, było to, że jeśli którekolwiek z pól tabeli głównej były przeszukiwane, wybrałem tabelę tymczasową tylko na tych polach. WTEDY dołączyłem do wszystkich stołów z tym stołem tymczasowym przed wykonaniem pozostałej części wyszukiwania. Wyszukiwanie miejsc, w których jedno z głównych pól tabeli zajmuje teraz mniej niż 10 sekund.

Jeśli żadne z pól głównej tabeli nie jest rozpoczęte, wykonuję podobne optymalizacje dla innych tabel. Kiedy skończyłem, żadne wyszukiwanie nie trwa dłużej niż 30 sekund, a większość ma mniej niż 10 lat.

Wykorzystanie procesora przez serwer SQL również spadło.


@BoltBait: Czy komunikat na wynos, że zawsze powinieneś próbować zmniejszyć liczbę wierszy przed wykonaniem łączenia?
unutbu

Z pewnością zdziałało cuda w moim przypadku. Ale nie optymalizowałbym systemu, dopóki nie będzie to konieczne.
BoltBait

normalnie na złączeniach nie są generowane żadne dane tymczasowe (w zależności oczywiście od selektywności, dostępnej pamięci i rozmiaru buforów złączeń), AFAIK; jednak dane tymczasowe są zwykle tworzone na zamówienie i odrębne, jeśli nie ma indeksu, który można by wykorzystać do takich operacji.
Bez powodu

1

Podczas gdy sprzężenia (prawdopodobnie ze względu na znormalizowany projekt) mogą oczywiście być wolniejsze w przypadku pobierania danych niż odczyt z pojedynczej tabeli, zdenormalizowana baza danych może być wolna w przypadku operacji tworzenia / aktualizacji danych, ponieważ ślad całej transakcji nie będzie minimalny.

W znormalizowanej bazie danych część danych będzie znajdować się tylko w jednym miejscu, więc ślad dla aktualizacji będzie jak najmniejszy. W zdenormalizowanej bazie danych możliwe jest, że ta sama kolumna w wielu wierszach lub między tabelami będzie musiała zostać zaktualizowana, co oznacza, że ​​ślad byłby większy, a ryzyko blokad i zakleszczeń może wzrosnąć.


1

Cóż, tak, wybieranie wierszy z jednej zdenormalizowanej tabeli (zakładając przyzwoite indeksy dla zapytania) może być szybsze niż wybieranie wierszy utworzonych z łączenia kilku tabel, szczególnie jeśli łączenia nie mają dostępnych wydajnych indeksów.

Przykłady przytoczone w artykule - Flickr i eBay - to wyjątkowe przypadki IMO, więc miej (i zasługują) na wyjątkowe odpowiedzi. Autor szczególnie zwraca uwagę na brak RI i zakres powielania danych w artykule.

Większość aplikacji - znowu IMO - korzysta z walidacji i ograniczonego powielania zapewnianego przez RDBMS.


0

Mogą być powolne, jeśli są wykonywane niechlujnie. Na przykład, jeśli wykonasz 'select *' na złączeniu, prawdopodobnie zajmie trochę czasu, aby odzyskać rzeczy. Jeśli jednak uważnie wybierzesz, które kolumny mają zostać zwrócone z każdej tabeli, i przy odpowiednich indeksach, nie powinno być problemu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.