select * vs select kolumna


124

Jeśli potrzebuję tylko 2/3 kolumn i wykonuję zapytanie SELECT *zamiast dostarczania tych kolumn w zapytaniu wybierającym, czy występuje spadek wydajności dotyczący większej / mniejszej liczby operacji we / wy lub pamięci?

Narzut sieci może występować, jeśli wybiorę * bez potrzeby.

Ale czy w operacji wybierania silnik bazy danych zawsze pobiera atomową krotkę z dysku, czy też pobiera tylko te kolumny, których zażądano w operacji wybierania?

Jeśli zawsze pobiera krotkę, narzut we / wy jest taki sam.

W tym samym czasie może wystąpić zużycie pamięci na usunięcie żądanych kolumn z krotki, jeśli pobierze krotkę.

Więc jeśli tak jest, wybierz jakąś kolumnę będzie miała więcej narzutu pamięci niż ta z select *


Czy jest jakiś konkretny RDBMS, o który pytasz? Możliwe, że sposób SELECTwykonywania / przetwarzania zapytań różni się w zależności od bazy danych.
Lèse majesté

10
CREATE VIEW foo_view AS SELECT * FROM foo;Nawiasem mówiąc , w PostgreSQL, jeśli powiesz , a następnie dodasz kolumny do tabeli foo później, te kolumny nie pojawią się automatycznie w foo_view zgodnie z oczekiwaniami. Innymi słowy, *w tym kontekście rozwija się tylko raz (w czasie tworzenia widoku), a nie na SELECT. Z powodu komplikacji wynikających z ALTER TABLE, powiedziałbym, że (w praktyce) *jest uważane za szkodliwe.
Joey Adams,

@JoeyAdams - nie tylko PostgresQL, takie jest także zachowanie Oracle.
APC,

1
@OMG Kucyki: Nie wiedziałem o podobnym wpisie. Jednak te nie są naprawdę podobne. @ Lèse majesté: Mówię o Generic RDBMS. nie o żadnym konkretnym dostawcy @Joey Adams: Hmm, wiem, że * jest niebezpieczne. chcę tylko omówić kwestie dotyczące wydajności.
Neel Basu

Odpowiedzi:


31

Zawsze pobiera krotkę (z wyjątkiem przypadków, gdy tabela została podzielona w pionie - podzielona na kolumny), więc odpowiadając na zadane pytanie, nie ma to znaczenia z punktu widzenia wydajności. Jednak z wielu innych powodów (poniżej) należy zawsze wybierać dokładnie te kolumny, które chcesz, według nazwy.

Zawsze pobiera krotkę, ponieważ (w każdym znanym mi systemie RDBMS sprzedawców) podstawowa struktura pamięci dyskowej dla wszystkiego (w tym danych tabeli) jest oparta na zdefiniowanych stronach we / wy (np. W SQL Server każda strona jest 8 kilobajtów). I każdy odczyt lub zapis we / wy odbywa się według strony. To znaczy, każdy zapis lub odczyt jest pełną stroną danych.

Z powodu tego podstawowego ograniczenia strukturalnego konsekwencją jest to, że każdy wiersz danych w bazie danych musi zawsze znajdować się na jednej i tylko jednej stronie. Nie może obejmować wielu stron danych (z wyjątkiem specjalnych rzeczy, takich jak obiekty blob, w których rzeczywiste dane obiektu blob są przechowywane w oddzielnych fragmentach strony, a rzeczywista kolumna wiersza tabeli otrzymuje tylko wskaźnik ...). Ale te wyjątki to tylko wyjątki i generalnie nie mają zastosowania, z wyjątkiem szczególnych przypadków (dla specjalnych typów danych lub pewnych optymalizacji dla specjalnych okoliczności).
Nawet w tych specjalnych przypadkach, ogólnie rzecz biorąc, sam wiersz tabeli danych (który zawiera wskaźnik do rzeczywistych danych dla obiektu Blob lub cokolwiek innego), musi być przechowywany na jednej stronie IO ...

WYJĄTEK. Jedyne miejsce, w którym Select *jest OK, znajduje się w zapytaniu podrzędnym po klauzuli Existslub Not Existspredykatu, na przykład:

   Select colA, colB
   From table1 t1
   Where Exists (Select * From Table2
                 Where column = t1.colA)

EDYCJA: Aby odnieść się do komentarza @Mike Sherer, tak, to prawda, zarówno pod względem technicznym, z odrobiną definicji dla twojego specjalnego przypadku, jak i estetycznie. Po pierwsze, nawet jeśli zestaw żądanych kolumn jest podzbiorem kolumn przechowywanych w jakimś indeksie, procesor zapytań musi pobrać każdą kolumnę przechowywaną w tym indeksie, a nie tylko żądane, z tych samych powodów - WSZYSTKIE I / O muszą być wykonane w stron, a dane indeksu są przechowywane na stronach we / wy, podobnie jak dane tabeli. Jeśli więc zdefiniujesz „krotkę” dla strony indeksu jako zestaw kolumn przechowywanych w indeksie, instrukcja nadal będzie prawdziwa.
a stwierdzenie jest prawdziwe estetycznie, ponieważ chodzi o to, że pobiera dane na podstawie tego, co jest przechowywane na stronie I / O, a nie na podstawie tego, o co prosisz, i to prawda, niezależnie od tego, czy uzyskujesz dostęp do strony I / O tabeli bazowej, czy indeksu Strona I / O.

Z innych powodów, których nie należy używać Select *, zobacz Dlaczego jest SELECT *uważany za szkodliwy? :


„Zawsze pobiera krotkę”, czy na pewno? Hmm OK Więc miałem rację. jeśli tak jest, przypadek select *będzie miał mniejszy narzut pamięci niż ten select columnsam narzut we / wy. więc jeśli zostawimy narzut sieci. select *jeśli jest mniejszy niż ten zselect column
Neel Basu

10
To nie jest prawda. Jednym z przykładów z góry mojej głowy jest to, gdy chcesz tylko wartość zindeksowanej kolumny w MySQL (na przykład, aby sprawdzić istnienie wiersza) i używasz silnika pamięci MyISAM, pobierze dane z Plik MYI, który może znajdować się w pamięci, a nawet nie trafić na dysk!
Mike Sherov,

Tak, jeśli żądany zestaw krotek jest w pamięci, nie będzie żadnych operacji wejścia / wyjścia, ale to jest specjalny przypadek. Więc co to jest lato. Jeśli wybiorę jakąś zindeksowaną kolumnę, cała krotka nie zostanie odczytana? inaczej czytana jest cała krotka?
Neel Basu,

Nie jestem do końca pewien, jak MySql wykonuje buforowanie, ale w SQL Server i Oracle, nawet jeśli dane są w pamięci podręcznej w pamięci, nadal uzyskuje do nich dostęp przy użyciu tej samej struktury strony, jaką miałby podczas uzyskiwania dostępu do niego z dysku. co oznacza, że ​​wymagałoby to jednego wejścia / wyjścia pamięci na stronę danych ... dokładnie tak samo, jak z dysku. (z wyjątkiem, że wejścia / wyjścia pamięci są oczywiście znacznie szybsze niż dyskowe wejścia / wyjścia). Rzeczywiście, jest to cel projektowania buforowania, aby proces dostępu był całkowicie niezależny od lokalizacji danych.
Charles Bretana,

2
Czy możesz powiedzieć więcej „z wielu innych powodów”? Ponieważ nie były one dla mnie jasne. Jeśli wydajność nie ma znaczenia, po co zwracać uwagę na żądania nazw kolumn?
Dennis

111

Jest kilka powodów, dla których nigdy (przenigdy) nie powinieneś używać SELECT *w kodzie produkcyjnym:

  • ponieważ nie dajesz swojej bazie danych żadnych wskazówek, co chcesz, najpierw będzie musiała sprawdzić definicję tabeli, aby określić kolumny w tej tabeli. To wyszukiwanie będzie kosztować trochę czasu - niewiele w przypadku pojedynczego zapytania - ale sumuje się z czasem

  • jeśli potrzebujesz tylko 2/3 kolumn, wybierasz 1/3 za dużo danych, które muszą być pobierane z dysku i wysyłane przez sieć

  • jeśli zaczniesz polegać na pewnych aspektach danych, np. kolejności zwracanych kolumn, możesz spotkać się z przykrą niespodzianką po reorganizacji tabeli i dodaniu nowych kolumn (lub usunięciu istniejących)

  • w SQL Server (brak pewności co do innych baz danych), jeśli potrzebujesz podzbioru kolumn, zawsze istnieje szansa, że ​​indeks nieklastrowy może pokryć to żądanie (zawiera wszystkie potrzebne kolumny). Z a SELECT *, od samego początku rezygnujesz z tej możliwości. W tym konkretnym przypadku dane byłyby pobierane ze stron indeksowych (jeśli zawierają one wszystkie niezbędne kolumny), a zatem obciążenie we / wy dysku i pamięć byłyby znacznie mniejsze w porównaniu z wykonywaniem SELECT *....zapytania.

Tak, początkowo wymaga to nieco więcej pisania (narzędzia takie jak SQL Prompt for SQL Server nawet Ci w tym pomogą) - ale tak naprawdę jest to jeden przypadek, w którym istnieje zasada bez wyjątku: nigdy nie używaj SELECT * w kodzie produkcyjnym. ZAWSZE.


13
zgadzając się z Tobą w praktyce, z pewnością masz rację we wszystkich przypadkach podczas pobierania danych kolumnowych z tabeli, ponieważ dotyczy tego pytania), podkreślenie przez cały rok EVER niemniej jednak skłania mnie do zwrócenia uwagi, że ta reguła nie jest ogólna dla WSZYSTKICH zapytań SQL. w szczególności jest używany w podzapytaniu po predykacie EXISTS, (tak jak w przypadku Where Exists (Select * From ...) użycie z Select *pewnością nie stanowi problemu, aw niektórych kręgach jest uważane za najlepszą praktykę.
Charles Bretana,

3
@Charles Bretana: tak, to IF EXISTS(SELECT *...jest szczególny przypadek - ponieważ nie ma danych, które są naprawdę pobierane, ale to tylko sprawdzenie istnienia, SELECT * nie jest problemem ...
marc_s

1
A co, jeśli tworzę interfejs API, który umożliwia pobieranie danych z jednej z moich tabel. Ponieważ nie wiedziałbym, jakimi danymi interesuje się użytkownik, przypuszczam, że SELECT * byłby do przyjęcia?
Simon Bengtsson,

1
@SimonBengtsson: Nadal bym się temu sprzeciwił - załóżmy, że masz jakieś dane „administracyjne” w określonych kolumnach w tabeli, których nie chcesz ujawniać klientowi? Chciałbym zawsze jednoznacznie określić listę kolumn do pobrania
marc_s

1
To prawda. A co z zapytaniem o widok, który został specjalnie skonfigurowany do użytku z interfejsem API?
Simon Bengtsson,

21

Powinieneś zawsze używać tylko selecttych kolumn, których naprawdę potrzebujesz. Nigdy nie jest mniej wydajne wybieranie mniej, a nie więcej, a ponadto napotkasz mniej nieoczekiwanych efektów ubocznych - takich jak dostęp do kolumn wyników po stronie klienta po indeksie, a następnie ich niepoprawne indeksy przez dodanie nowej kolumny do tabeli.

[edytuj]: Oznaczało dostęp. Głupi mózg wciąż się budzi.


3
+1 dla skrajnego przypadku, o którym myślę, że niewielu pomyśli na pierwszy rzut oka - indeksy po stronie klienta i dodane / zmienione kolumny.
Tomas Aschan,

1
Tak, ale czy często używane są indeksy numeryczne w kolumnach? Zawsze uzyskiwałem dostęp do danych kolumn za pomocą kluczy ciągów lub nazw właściwości, jeśli używam ORM.
Lèse majesté

11
Widziałem to dawno temu, młodszy programista wybrał * z tabeli i przyjął założenia dotyczące kolejności kolumn; cały jego kod się zepsuł, gdy ktoś inny zmienił stół. Co za zabawa.
Paul McKenzie,

7
Prawdopodobnie złym pomysłem jest używanie ogólnej kolejności kolumn tylko ze względu na czytelność kodu, a podwójnie złe używanie SELECT *z tym.
Lèse majesté

2
Wow, dostęp do kolumn według indeksu w kodzie klienta wydaje się fenomenalnie złym pomysłem. Dla tej sprawy, powołując się na kolejności, w jakiej pojawiają się kolumny w tabeli wynikowej w jakikolwiek sposób czuje się bardzo brudny do mnie.
Matt Peterson

7

O ile nie przechowujesz dużych obiektów blob, wydajność nie jest problemem. Głównym powodem, dla którego nie należy używać funkcji SELECT *, jest to, że jeśli używasz zwracanych wierszy jako krotek, kolumny wracają w dowolnej kolejności, którą określa schemat, a jeśli to się zmieni, będziesz musiał naprawić cały kod.

Z drugiej strony, jeśli używasz dostępu w stylu słownikowym, nie ma znaczenia, w jakiej kolejności wracają kolumny, ponieważ zawsze uzyskujesz do nich dostęp po nazwie.


6

To natychmiast przywodzi mi na myśl tabelę, której używałem, która zawierała kolumnę typu blob; zwykle zawierał obraz JPEG o Mbrozmiarze kilku sekund.

Nie trzeba dodawać, że nie zrobiłem SELECTtego artykułu, chyba że naprawdę tego potrzebowałem. Posiadanie tych danych unoszących się dookoła - zwłaszcza gdy wybrałem wiele wierszy - było po prostu kłopotliwe.

Jednak przyznam, że w przeciwnym razie zwykle odpytuję o wszystkie kolumny w tabeli.


20
Kolumny LOB są zawsze moim ulubionym przykładem niebezpieczeństw SELECT *. Tak więc miałem cię zagłosować, dopóki nie przeczytałem trzeciego akapitu. TSK TSK. Co się stanie, jeśli inny programista doda BLOB do tabeli, która obecnie nie ma takiej kolumny?
APC,

1
@APC, chciałbym móc bardziej zagłosować za Twój komentarz. Pomyśl o swoim biednym współpracowniku, który po prostu chce dodać kolumnę bez powodowania ogromnego załamania wydajności! Pomyśl, jak bardzo się złoszczą, gdy po kilku godzinach odkryją Twoją niewinnie wyglądającą selekcję *.
Mike Sherov

1
@ user256007, tak, nawet bez BLOBa ... BLOB tylko ilustruje skrajny przykład. Sprawdź moją odpowiedź dla Charlesa, czasami wybranie określonych kolumn może umożliwić ci pobranie danych z pamięci bez konieczności wchodzenia na dysk!
Mike Sherov

1
@Richard, myślę, że są świetne, gdy optymalizacja wydajności bazy danych nie jest twoim głównym zmartwieniem, czyli w 99% przypadków. Podobnie jak w przypadku większości frameworków, mają tendencję do generalizowania rzeczy, aby umożliwić szybszy rozwój, poświęcając czystą wydajność. Jak powiedział Knuth: „Przedwczesna optymalizacja jest źródłem wszelkiego zła”. Kiedy dojdziesz do punktu, w którym musisz się martwić o wydajność wybranych kolumn w porównaniu z select * (zapytaj Twittera o RoR), możesz się tym martwić i zoptymalizować. Jeśli framework nie jest wystarczająco mocny, aby to obsługiwać, powiedziałbym, że używasz złego frameworka.
Mike Sherov,

1
@ user256007 - ogólna zasada brzmi „nie używaj SELECT *”. Odpowiedź udzielona przez marc_s ma wszystkie powody, dla których tak jest.
APC,

6

Podczas wyboru SQL baza danych zawsze będzie odwoływać się do metadanych tabeli, niezależnie od tego, czy jest to SELECT * dla SELECT a, b, c ... Dlaczego? Bo tam znajdują się informacje o strukturze i układzie tabeli w systemie.

Musi przeczytać te informacje z dwóch powodów. Po pierwsze, aby po prostu skompilować oświadczenie. Musi upewnić się, że określisz co najmniej istniejącą tabelę. Ponadto struktura bazy danych mogła ulec zmianie od czasu ostatniego wykonania instrukcji.

Oczywiście metadane bazy danych są buforowane w systemie, ale nadal trzeba je przetwarzać.

Następnie metadane są używane do generowania planu zapytania. Dzieje się tak za każdym razem, gdy kompilowana jest instrukcja. Ponownie, działa to w przypadku metadanych zapisanych w pamięci podręcznej, ale zawsze jest to robione.

Jedynym przypadkiem, w którym to przetwarzanie nie jest wykonywane, jest sytuacja, gdy baza danych używa wstępnie skompilowanego zapytania lub buforuje poprzednie zapytanie. To jest argument przemawiający za używaniem parametrów wiązania zamiast dosłownego SQL. „SELECT * FROM TABLE WHERE key = 1” to inne zapytanie niż „SELECT * FROM TABLE WHERE key =?” a „1” jest związane z wezwaniem.

Bazy danych w dużym stopniu polegają na buforowaniu stron, aby działać. Wiele nowoczesnych baz danych jest wystarczająco małych, aby całkowicie zmieścić się w pamięci (lub, być może powinienem powiedzieć, nowoczesna pamięć jest wystarczająco duża, aby pomieścić wiele DB). Następnie głównym kosztem we / wy na zapleczu jest rejestrowanie i opróżnianie stron.

Jeśli jednak nadal trafiasz na dysk dla swojej bazy danych, podstawową optymalizacją wykonywaną przez wiele systemów jest poleganie na danych w indeksach, a nie na samych tabelach.

Jeśli masz:

CREATE TABLE customer (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(150) NOT NULL,
    city VARCHAR(30),
    state VARCHAR(30),
    zip VARCHAR(10));

CREATE INDEX k1_customer ON customer(id, name);

Następnie, jeśli wykonasz „SELECT id, name FROM customer WHERE id = 1”, jest bardzo prawdopodobne, że baza danych pobierze te dane z indeksu, a nie z tabel.

Czemu? Prawdopodobnie i tak użyje indeksu, aby spełnić zapytanie (w porównaniu ze skanowaniem tabeli), i chociaż „nazwa” nie jest używana w klauzuli where, indeks ten nadal będzie najlepszą opcją dla zapytania.

Teraz baza danych zawiera wszystkie dane potrzebne do spełnienia zapytania, więc nie ma powodu, aby same trafiać na strony tabeli. Korzystanie z indeksu skutkuje mniejszym ruchem na dysku, ponieważ masz większą gęstość wierszy w indeksie niż ogólnie w tabeli.

Jest to faliste wyjaśnienie konkretnej techniki optymalizacji używanej w niektórych bazach danych. Wiele z nich ma kilka technik optymalizacji i strojenia.

Ostatecznie SELECT * jest przydatne w przypadku dynamicznych zapytań, które trzeba wpisywać ręcznie, nigdy bym go nie używał do „prawdziwego kodu”. Identyfikacja poszczególnych kolumn daje DB więcej informacji, których może użyć do optymalizacji zapytania i daje lepszą kontrolę nad kodem przed zmianami schematu itp.


Will, odrzuciłem twoją odpowiedź tylko dlatego, że używasz NOT NULL razem z KLUCZEM PODSTAWOWYM. Czy jest dobry powód, żeby pisać w ten sposób?
Learner

4

Myślę, że nie ma dokładnej odpowiedzi na Twoje pytanie, ponieważ zastanawiasz się nad wydajnością i łatwością obsługi swoich aplikacji. Select columnjest bardziej wydajne select *, ale jeśli tworzysz zorientowany system obiektowy, spodoba ci się używanie object.propertiesi możesz potrzebować właściwości w dowolnej części aplikacji, wtedy będziesz potrzebować napisać więcej metod, aby uzyskać właściwości w specjalnych sytuacjach, jeśli nie użyj select *i wypełnij wszystkie właściwości. Twoje aplikacje muszą mieć dobrą wydajność, select *aw niektórych przypadkach będziesz musiał użyć kolumny wyboru, aby poprawić wydajność. Wtedy będziesz mieć lepszy z dwóch światów, łatwość pisania i utrzymywania aplikacji oraz wydajność, gdy potrzebujesz wydajności.


4

Przyjęta tutaj odpowiedź jest błędna. Natknąłem się na to, gdy inne pytanie zostało zamknięte jako duplikat tego (gdy nadal pisałem swoją odpowiedź - grr - stąd poniższy SQL odwołuje się do drugiego pytania).

Należy zawsze używać atrybutu SELECT, atrybutu .... NOT SELECT *

Dotyczy to głównie problemów z wydajnością.

SELECT name FROM users WHERE name = 'John';

Nie jest to zbyt przydatny przykład. Zamiast tego rozważ:

SELECT telephone FROM users WHERE name='John';

Jeśli istnieje indeks (nazwisko, telefon), wówczas zapytanie można rozwiązać bez konieczności wyszukiwania odpowiednich wartości w tabeli - istnieje indeks obejmujący .

Co więcej, załóżmy, że w tabeli znajduje się BLOB zawierający zdjęcie użytkownika i przesłane CV oraz arkusz kalkulacyjny… używając SELECT * ściągnie wszystkie te informacje z powrotem do buforów DBMS (wymuszając inne przydatne informacje z pamięci podręcznej). Następnie wszystko zostanie wysłane do klienta, wykorzystując czas w sieci i pamięć klienta na dane, które są nadmiarowe.

Może również powodować problemy funkcjonalne, jeśli klient pobiera dane jako wyliczoną tablicę (np. Mysql_fetch_array ($ x, MYSQL_NUM) PHP). Być może, gdy kod został zapisany, „telefon” była trzecią kolumną zwracaną przez SELECT *, ale potem ktoś podchodzi i decyduje się dodać adres e-mail do tabeli, umieszczony przed „telefon”. Żądane pole jest teraz przesunięte do czwartej kolumny.


2

Tak czy inaczej są powody. Często używam SELECT * w PostgreSQL, ponieważ jest wiele rzeczy, które możesz zrobić z SELECT * w PostgreSQL, a których nie możesz zrobić z jawną listą kolumn, szczególnie w procedurach składowanych. Podobnie w Informix, polecenie SELECT * w dziedziczonym drzewie tabeli może dać postrzępione wiersze, podczas gdy jawna lista kolumn nie może, ponieważ zwracane są również dodatkowe kolumny w tabelach podrzędnych.

Głównym powodem, dla którego robię to w PostgreSQL, jest to, że zapewnia to, że otrzymam dobrze sformułowany typ specyficzny dla tabeli. To pozwala mi wziąć wyniki i użyć ich jako typu tabeli w PostgreSQL. Pozwala to również na znacznie więcej opcji w zapytaniu niż sztywna lista kolumn.

Z drugiej strony sztywna lista kolumn umożliwia sprawdzenie na poziomie aplikacji, czy schematy bazy danych nie uległy zmianie w określony sposób, co może być pomocne. (Robię takie kontrole na innym poziomie.)

Jeśli chodzi o wydajność, zwykle używam WIDOKÓW i procedur składowanych zwracających typy (a następnie listy kolumn wewnątrz procedury składowanej). To daje mi kontrolę nad tym, jakie typy są zwracane.

Ale pamiętaj, że używam SELECT * zwykle przeciwko warstwie abstrakcji, a nie tabelom bazowym.


2

Odniesienie zaczerpnięte z tego artykułu:

Bez funkcji SELECT *: Jeśli używasz „SELECT *” w tym momencie, wybierasz więcej kolumn z bazy danych, a niektóre z tych kolumn mogą nie być używane przez aplikację. Spowoduje to dodatkowe koszty i obciążenie systemu bazy danych oraz większą ilość danych przesyłanych przez sieć.

Z SELECT *: Jeśli masz specjalne wymagania i stworzyłeś dynamiczne środowisko, po dodaniu lub usunięciu kolumny automatycznie obsługiwane przez kod aplikacji. W tym szczególnym przypadku nie musisz zmieniać kodu aplikacji i bazy danych, co automatycznie wpłynie na środowisko produkcyjne. W takim przypadku możesz użyć „SELECT *”.


0

Aby dodać niuans do dyskusji, którego tutaj nie widzę: Jeśli chodzi o I / O, jeśli używasz bazy danych z pamięcią kolumnową , możesz zrobić DUŻO mniej I / O, jeśli zapytasz tylko o pewne kolumny. Gdy przechodzimy na dyski SSD, korzyści mogą być nieco mniejsze w porównaniu z pamięcią opartą na wierszach, ale istnieje a) odczytywanie tylko bloków zawierających kolumny, na których Ci zależy b) kompresja, która ogólnie znacznie zmniejsza rozmiar danych na dysku, a tym samym ilość danych odczytanych z dysku.

Jeśli nie jesteś zaznajomiony z magazynowaniem kolumnowym, jedna implementacja Postgres pochodzi z Citus Data, inna to Greenplum, inna Paraccel, a inna (luźno mówiąc) to Amazon Redshift. Dla MySQL istnieje Infobright, prawie nieistniejąca już InfiniDB. Inne oferty handlowe obejmują Vertica firmy HP, Sybase IQ, Teradata ...


-1
select * from table1 INTERSECT  select * from table2

równy

select distinct t1 from table1 where Exists (select t2 from table2 where table1.t1 = t2 )

Czy mógłbyś sformatować kod, podświetlając go i naciskając Ctrl + K
WhatsThePoint
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.