Który jest szybszy / najlepszy? SELECT * lub SELECT kolumna1, kolumna2, kolumna3 itd

166

Słyszałem, że SELECT *ogólnie jest to zła praktyka podczas pisania poleceń SQL, ponieważ jest bardziej wydajna w przypadku SELECTkolumn, których potrzebujesz.

Jeśli potrzebuję SELECTkażdej kolumny w tabeli, powinienem użyć

SELECT * FROM TABLE

lub

SELECT column1, colum2, column3, etc. FROM TABLE

Czy wydajność naprawdę ma znaczenie w tym przypadku? Myślę, że SELECT *byłoby bardziej optymalne wewnętrznie, gdybyś naprawdę potrzebował wszystkich danych, ale mówię to bez prawdziwego zrozumienia bazy danych.

Ciekawi mnie, jaka jest najlepsza praktyka w tym przypadku.

AKTUALIZACJA: Prawdopodobnie powinienem określić, że jedyną sytuacją, w której naprawdę chciałbym to zrobić, SELECT *jest wybranie danych z jednej tabeli, o której wiem, że wszystkie kolumny będą zawsze musiały zostać pobrane, nawet gdy zostaną dodane nowe kolumny.

Biorąc jednak pod uwagę odpowiedzi, które widziałem, nadal wydaje się to złym pomysłem i SELECT *nigdy nie powinno być używane z dużo bardziej technicznych powodów, o których myślałem.

Dan Herbert
źródło

Odpowiedzi:

168

Jednym z powodów, dla których wybranie określonych kolumn jest lepsze, jest to, że zwiększa prawdopodobieństwo, że SQL Server może uzyskać dostęp do danych z indeksów, zamiast odpytywania danych tabeli.

Oto post, który o tym napisałem: Prawdziwym powodem zapytań wybierających jest złe pokrycie indeksu

Jest również mniej kruchy do zmiany, ponieważ każdy kod, który zużywa dane, będzie miał taką samą strukturę danych, niezależnie od zmian wprowadzonych w schemacie tabeli w przyszłości.

Jon Galloway
źródło
3
+1 za to. Jeśli wszystkie kolumny, do których się odwołujemy, znajdują się w jednym indeksie („indeksie pokrywającym”), trafiłeś na złoty poziom.
Ian Nelson,
22
to nie jest odpowiedź na jego pytanie - "Jeśli muszę WYBRAĆ każdą kolumnę w tabeli, ..." - w takim przypadku * vs col1, .., coln nie ma znaczenia (ale TAKIE POTRZEBUJE programista, ponieważ * jest krótszy!).
Matt Rogish,
3
Nadal ma to znaczenie, ponieważ lista wyboru jest formą kontraktu, zwłaszcza jeśli SQL znajduje się w procedurze składowanej.
Eric Z Beard,
4
Chociaż to, co mówi Jon, jest całkowicie poprawne i jest to bardzo ważny punkt, muszę zgodzić się, że pytanie JAK ZADAWANE dotyczy tego, czy już pytają o wszystkie kolumny. Z powodu tej części pytania prawdziwym problemem jest kruchość w obliczu zmian schematu.
IDisposable
1
@MattRogish proszę pana. Czy jest jakaś różnica w wydajności między tymi dwiema metodami (* vsall_column_names), skoro mamy tysiące wierszy i wykonujemy polecenie SELECT z indeksem (w klauzuli WHERE)?
Santosh
59

Biorąc swoją specyfikację, które wybierając wszystkie kolumny, nie ma różnicy w tym czasie . Pamiętaj jednak, że schematy bazy danych się zmieniają. Jeśli użyjesz SELECT *, dostaniesz jakiekolwiek nowe kolumny dodane do tabeli, nawet jeśli najprawdopodobniej twój kod nie jest przygotowany do używania lub prezentowania tych nowych danych. Oznacza to, że narażasz swój system na nieoczekiwane zmiany wydajności i funkcjonalności.

Możesz chcieć odrzucić to jako niewielki koszt, ale pamiętaj, że kolumny, których nadal nie potrzebujesz, muszą zawierać:

  1. Odczytaj z bazy danych
  2. Wysłano przez sieć
  3. Wpisane w twój proces
  4. (dla technologii typu ADO) Zapisane w tabeli danych w pamięci
  5. Zignorowano i odrzucono / zebrano śmieci

Pozycja nr 1 wiąże się z wieloma ukrytymi kosztami, w tym wyeliminowaniem potencjalnego indeksu, powodując ładowanie stron danych (i niszczenie pamięci podręcznej serwera), generowanie blokad wierszy / stron / tabel, których można by uniknąć w inny sposób.

Zrównoważyć to z potencjalnymi oszczędnościami wynikającymi z określenia kolumn w porównaniu z, *a jedyne potencjalne oszczędności to:

  1. Programista nie musi ponownie odwiedzać SQL, aby dodać kolumny
  2. Transport sieciowy SQL jest mniejszy / szybszy
  3. Czas analizy / walidacji zapytania SQL Server
  4. Pamięć podręczna planu kwerend programu SQL Server

W przypadku pozycji 1 rzeczywistość jest taka, że ​​zamierzasz dodać / zmienić kod, aby użyć dowolnej nowej kolumny, którą i tak możesz dodać, więc jest to pranie.

W przypadku punktu 2 różnica rzadko jest na tyle duża, aby popchnąć Cię do innego rozmiaru pakietu lub liczby pakietów sieciowych. Jeśli dojdziesz do momentu, w którym czas transmisji instrukcji SQL jest dominującym problemem, prawdopodobnie musisz najpierw zmniejszyć szybkość instrukcji.

W przypadku pozycji 3 NIE ma żadnych oszczędności, ponieważ rozszerzenie *tabeli i tak musi nastąpić, co i tak oznacza sprawdzenie schematu tabeli (ów). Realistycznie, umieszczenie kolumn na liście będzie wiązało się z tym samym kosztem, ponieważ muszą zostać sprawdzone pod kątem schematu. Innymi słowy, jest to pełne mycie.

W przypadku pozycji 4, kiedy określisz konkretne kolumny, pamięć podręczna planu zapytań może się zwiększyć, ale tylko wtedy, gdy masz do czynienia z różnymi zestawami kolumn (co nie jest tym, co określono). W takim przypadku chcesz mieć różne wpisy w pamięci podręcznej, ponieważ potrzebujesz różnych planów w razie potrzeby.

Tak więc wszystko sprowadza się, ze względu na sposób, w jaki określiłeś pytanie, do odporności na problemy w obliczu ewentualnych modyfikacji schematu. Jeśli nagrywasz ten schemat do ROM (zdarza się), to jest *to całkowicie akceptowalne.

Jednak moją ogólną wskazówką jest to, że powinieneś wybierać tylko te kolumny, których potrzebujesz, co oznacza, że czasami będzie wyglądać tak, jakbyś prosił o wszystkie z nich, ale bazy danych i ewolucja schematu oznaczają, że mogą pojawić się nowe kolumny, które mogą znacznie wpłynąć na zapytanie .

Moja rada jest taka, że ZAWSZE WYBIERAJ określone kolumny . Pamiętaj, że w tym, co robisz, stajesz się dobry, więc po prostu zdobądź nawyk robienia tego dobrze.

Jeśli zastanawiasz się, dlaczego schemat może się zmienić bez zmiany kodu, pomyśl w kategoriach rejestrowania audytu, dat wejścia w życie / wygaśnięcia i innych podobnych rzeczy, które są dodawane przez administratorów baz danych w celu systemowego rozwiązywania problemów ze zgodnością. Innym źródłem podstępnych zmian są denormalizacje wydajności w innym miejscu systemu lub w polach zdefiniowanych przez użytkownika.

IDisposable
źródło
3
„Rzeczywistość jest taka, że ​​zamierzasz dodać / zmienić kod, aby użyć dowolnej nowej kolumny, którą i tak mógłbyś dodać, więc jest to pranie”. -Tylko jeśli ręcznie odczytujesz każdą kolumnę według nazwy w swoim kodzie. Jeśli używasz automatycznego mapowania, tak nie jest i ten problem staje się znaczący.
Josh Noe
36

Powinieneś wybrać tylko te kolumny, których potrzebujesz. Nawet jeśli potrzebujesz wszystkich kolumn, nadal lepiej jest podać nazwy kolumn, aby serwer sql nie musiał odpytywać tabeli systemowej o kolumny.

Ponadto aplikacja może się zepsuć, jeśli ktoś doda kolumny do tabeli. Twój program otrzyma kolumny, których też się nie spodziewał i może nie wiedzieć, jak je przetworzyć.

Poza tym, jeśli tabela ma kolumnę binarną, zapytanie będzie znacznie wolniejsze i zużyje więcej zasobów sieciowych.

Giorgi
źródło
6
Aha, więc używając * dodajesz dodatkową pracę dla DB. Ok, to jeden z powodów, o których nie pomyślałem.
Ankur
1
+1 za ryzyko wczesnego złamania / wyłapania błędów. Myślę, że dyskusja o wydajności jest ważna, ale YAGNI.
Nailitdown
6
Czy serwer SQL nie musiałby mimo wszystko walidować lub sprawdzać, czy „col1” znajduje się w określonej tabeli, tj. W tabeli systemu zapytań?
Patrick,
3
Największy spadek wydajności jest prawdopodobnie związany z indeksowaniem. Jeśli kolumna, której szukasz, jest częścią indeksu używanego do znalezienia danych, serwer pobierze dane właśnie tam, jeśli wybierzesz *, najprawdopodobniej będzie musiał wykonać coś, co nazywa się wyszukiwaniem zakładek, co wymaga dodatkowego skanuj, aby znaleźć pozostałe dane, których możesz nawet nie potrzebować.
Cobusve
3
@Patrick - Spot on. Jest wiele dobrych powodów, aby unikać *, ale to nie jest jeden z nich.
Martin Smith
31

Istnieją cztery ważne powody, dla których select *jest źle:

  1. Najważniejszym praktycznym powodem jest to, że zmusza użytkownika do magicznego poznania kolejności, w jakiej kolumny zostaną zwrócone. Lepiej być wyraźnym, co również chroni przed zmianą stołu, który ładnie przechodzi w ...

  2. Jeśli nazwa kolumny, której używasz, ulegnie zmianie, lepiej jest ją wychwycić wcześnie (w momencie wywołania SQL), niż gdy próbujesz użyć kolumny, która już nie istnieje (lub zmieniła jej nazwę itp.) )

  3. Podanie nazw kolumn sprawia, że ​​kod jest znacznie bardziej samodokumentowany, a więc prawdopodobnie bardziej czytelny.

  4. Jeśli przenosisz się przez sieć (lub nawet jeśli nie jesteś), kolumny, których nie potrzebujesz, są po prostu marnotrawstwem.

pkh
źródło
7
„Najważniejszym praktycznym powodem jest to, że zmusza użytkownika do magicznego poznania kolejności, w jakiej kolumny zostaną zwrócone”. Nie rozumiem, jak to jest problem. W każdym nowoczesnym kliencie DB odczytujesz kolumny według nazwy, a nie kolejności.
Josh Noe
Zwykle uruchamiam swój SQL przez interfejs C, więc tak naprawdę nie wiedziałbym, jaki jest stan wiedzy na temat „klientów DB”. Ale myślę, że prawdopodobnie ten rodzaj klienta, o którym mówisz, wykonuje jakąś niestandardową magię nie-SQL. (np. w SQLite, wysłanie zapytania do sqlite3_master, aby dowiedzieć się, jak zmienić *nazwę na zestaw).
pkh
A dalej od tego, ile osób pisze kod w nowoczesnych aplikacjach, które używają indeksu nazw kolumn? Większość ludzi z pewnością używa jakiegoś programu do mapowania i całego stosu buforowania danych, które mogą być nieaktualne. Osobiście najpierw napisz kod, a później martw się, jeśli wystąpią problemy z wydajnością.
Colin Wiseman,
10

Określenie listy kolumn jest zwykle najlepszą opcją, ponieważ nie będzie to miało wpływu na aplikację, jeśli ktoś doda / wstawi kolumnę do tabeli.

ilitirit
źródło
7

Określanie nazw kolumn jest zdecydowanie szybsze - dla serwera. Ale jeśli

  1. wydajność nie jest dużym problemem (na przykład jest to baza danych zawartości witryny internetowej z setkami, może tysiącami - ale nie milionami - wierszy w każdej tabeli); I
  2. Twoim zadaniem jest tworzenie wielu małych, podobnych aplikacji (np. ogólnodostępnych witryn zarządzanych treścią) przy użyciu wspólnej struktury, zamiast tworzenia złożonej, jednorazowej aplikacji; I
  3. ważna jest elastyczność (wiele dostosowań schematu db dla każdej witryny);

wtedy lepiej będzie trzymać się SELECT *. W naszym frameworku intensywne użycie SELECT * pozwala nam wprowadzić do tabeli nowe pole treści zarządzanej przez stronę internetową, dając mu wszystkie zalety CMS (wersjonowanie, przepływ pracy / zatwierdzenia itp.), Jednocześnie dotykając kodu tylko w kilka punktów zamiast kilkudziesięciu.

Wiem, że guru DB mnie za to nienawidzą - śmiało, głosuj na mnie - ale w moim świecie czas programisty jest ograniczony, a cykle procesora są obfite, więc odpowiednio dostosowuję to, co oszczędzam, a co marnuję.

Herb Caudill
źródło
1
Dzięki temu ORM są znacznie prostsze w użyciu. Kiedy zapytania są budowane przez przekazanie obiektu budującego zapytanie, niekoniecznie jest się świadomym, które kolumny były wymagane przez inne części kodu (sprawdzanie uprawnień, co masz). Aby ograniczyć liczbę kolumn, należałoby sprawdzać za każdym razem, gdy zapytanie wymaga napisania. To bezcelowe, IMO. Kiedy zapytania okazują się wolne (logi!), Można je poprawić.
bytepusher
6

SELECT * to zła praktyka, nawet jeśli zapytanie nie jest wysyłane przez sieć.

  1. Wybieranie większej ilości danych niż potrzeba sprawia, że ​​zapytanie jest mniej wydajne - serwer musi odczytywać i przesyłać dodatkowe dane, więc zajmuje to czas i powoduje niepotrzebne obciążenie systemu (nie tylko sieci, jak wspominali inni, ale także dysku, procesora itp. ). Ponadto serwer nie jest w stanie zoptymalizować zapytania tak dobrze, jak mógłby (na przykład użyć indeksu pokrywającego dla zapytania).
  2. Po pewnym czasie struktura tabeli może się zmienić, więc SELECT * zwróci inny zestaw kolumn. Tak więc Twoja aplikacja może pobrać zestaw danych o nieoczekiwanej strukturze i zepsuć się gdzieś w dół. Jawne określenie kolumn gwarantuje, że otrzymasz zestaw danych o znanej strukturze lub otrzymasz wyraźny błąd na poziomie bazy danych (np. „Nie znaleziono kolumny”).

Oczywiście wszystko to nie ma większego znaczenia dla małego i prostego systemu.

VladV
źródło
4

Jeśli chodzi o wydajność, SELECT z określonymi kolumnami może być szybszy (nie ma potrzeby wczytywania wszystkich danych). Jeśli zapytanie naprawdę używa WSZYSTKICH kolumn, nadal preferowane jest polecenie SELECT z jawnymi parametrami. Każda różnica prędkości będzie w zasadzie niezauważalna i zbliżona do stałego czasu. Pewnego dnia twój schemat się zmieni i jest to dobre zabezpieczenie, aby zapobiec problemom z tego powodu.

Yann Ramin
źródło
Mylisz się co do tego, co niezauważalne, ponieważ z kontroli, które przeprowadziłem na kilku bazach danych, było jasne, że wybranie każdej kolumny, nawet jeśli wszystkie, jest znacznie szybsze. W niektórych przypadkach było to trzy razy szybsze.
shahar eldad
4

Odpowiedziałem tutaj na wiele dobrych powodów, oto kolejny, o którym nie wspomniano.

Jawne nazwanie kolumn pomoże Ci w późniejszych pracach konserwacyjnych. W pewnym momencie będziesz wprowadzać zmiany lub rozwiązywać problemy i zaczniesz pytać „gdzie do cholery jest używana ta kolumna”.

Jeśli masz nazwy wymienione jawnie, znalezienie każdego odwołania do tej kolumny - poprzez wszystkie procedury składowane, widoki itp. - jest proste. Po prostu zrzuć skrypt CREATE dla swojego schematu bazy danych i przeszukaj go tekstowo.

Chris Wuestefeld
źródło
3

zdecydowanie definiując kolumny, ponieważ SQL Server nie będzie musiał wyszukiwać kolumn, aby je wyciągnąć. Jeśli zdefiniujesz kolumny, SQL może pominąć ten krok.

Nick Berardi
źródło
Jest to: 1) nieistotne, ponieważ SQL Server musi odwoływać się do schematu tabeli w dowolny sposób (w celu sprawdzenia poprawności nazw kolumn lub wyszukania znanych, prawidłowych nazw kolumn) 2) Nie dotyczy zadanego pytania, w którym występują odwołania do wszystkich kolumn. Jedyny problem, JAK ZAPYTAJ, to kruchość w / zmiany schematu.
IDisposable
Głosowano w dół, ponieważ i tak musi zweryfikować kolumny.
John Gibb
3

Zawsze lepiej jest określić potrzebne kolumny, jeśli pomyślisz o tym raz, SQL nie musi myśleć „wtf is *” za każdym razem, gdy wykonujesz zapytanie. Co więcej, ktoś później może dodać kolumny do tabeli, których w rzeczywistości nie potrzebujesz w zapytaniu, a w takim przypadku będzie lepiej, określając wszystkie kolumny.

BrewinBombers
źródło
1
To nie jest prawda: serwer SQL musi nadal analizować każdą kolumnę i sprawdzać, czy istnieje w katalogach, podczas gdy wie, że „*” tak (i ​​tak, * jest interpretowane na wszystkie kolumny). Tak czy inaczej, dla DBMS jest trywialnie łatwo zrobić jedną z nich (chyba że masz 24000 kolumn), więc założę się, że tak samo jest w obu przypadkach
Matt Rogish,
Myślę, że lepszym punktem, którego wielu brakuje i, niestety, ta odpowiedź dotyczy tylko drugorzędnie, jest to, że jeśli nastąpią zmiany schematu / tabeli (tj. Zostaną dodane nowe kolumny), nic nie zepsuje.
Sean Hanley,
1
Jest to kompletne czyszczenie, ponieważ wyszukiwanie kolumn dla rozszerzenia * jest takie samo, jak sprawdzanie poprawności podanych nazw kolumn.
IDisposable
3

Problem z „select *” polega na możliwości przeniesienia danych, których tak naprawdę nie potrzebujesz. Podczas rzeczywistego zapytania do bazy danych wybrane kolumny tak naprawdę nie są uwzględniane w obliczeniach. Naprawdę „ciężki” jest transport danych z powrotem do klienta, a każda kolumna, której tak naprawdę nie potrzebujesz, marnuje przepustowość sieci i wydłuża czas oczekiwania na zwrot zapytania.

Nawet jeśli używasz wszystkich kolumn pobranych z „select * ...”, to na razie. Jeśli w przyszłości zmienisz układ tabeli / widoku i dodasz więcej kolumn, zaczniesz wprowadzać je do wybranych, nawet jeśli ich nie potrzebujesz.

Innym punktem, w którym instrukcja „select *” jest zła, jest tworzenie widoku. Jeśli utworzysz widok za pomocą opcji „select *”, a później dodasz kolumny do tabeli, definicja widoku i zwrócone dane nie będą pasować i będziesz musiał ponownie skompilować widoki, aby ponownie działały.

Wiem, że pisanie „select *” jest kuszące, ponieważ naprawdę nie lubię ręcznie określać wszystkich pól w moich zapytaniach, ale kiedy twój system zacznie się rozwijać, zobaczysz, że warto poświęcić ten dodatkowy czas / wysiłku w określaniu pól, zamiast poświęcać więcej czasu i wysiłku na usuwanie błędów w widokach lub optymalizację aplikacji.

Alexandre Brasil
źródło
Punkt na WIDOKACH jest bardzo ważny. Nie tylko nie otrzymasz wszystkich kolumn, jeśli dodasz kolumny do tabeli (pomimo tego, co pomyślałby *), ale mogą nawet nie pasować do rzeczywistego układu tabeli.
Euro Micelli,
3

Chociaż jawne wyświetlanie kolumn jest dobre dla wydajności, nie daj się zwariować.

Więc jeśli używasz wszystkich danych, spróbuj SELECT * dla uproszczenia (wyobraź sobie, że masz wiele kolumn i wykonanie zapytania JOIN ... może być okropne). Następnie - zmierz. Porównaj z zapytaniem z jawnie wymienionymi nazwami kolumn.

Nie spekuluj na temat wydajności, zmierz ją!

Jawne listowanie pomaga najbardziej, gdy masz jakąś kolumnę zawierającą duże dane (jak treść postu lub artykułu) i nie potrzebujesz jej w danym zapytaniu. Wtedy nie zwracając go na serwerze bazy danych odpowiedzi, można zaoszczędzić czas, przepustowość i przepustowość dysku. Wynik zapytania będzie również mniejszy, co jest dobre dla każdej pamięci podręcznej zapytań.

Paweł Hajdan
źródło
3

Naprawdę powinieneś wybierać tylko te pola, których potrzebujesz, i tylko wymaganą liczbę, tj

SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)

Poza bazą danych dynamiczne zapytania niosą ze sobą ryzyko ataków iniekcyjnych i zniekształconych danych. Zwykle można to obejść za pomocą procedur składowanych lub zapytań parametrycznych. Ponadto (chociaż nie jest to duży problem) serwer musi generować plan wykonania za każdym razem, gdy wykonywane jest dynamiczne zapytanie.

Matthew Abbott
źródło
„serwer musi generować plan wykonania za każdym razem, gdy wykonywane jest dynamiczne zapytanie”, co, jak zakładam, spowalnia zapytanie. Dzięki.
Ankur
Problemy z wydajnością korzystania z dynamicznego sql byłyby prawdopodobnie realizowane tylko w scenariuszach z bardzo dużym obciążeniem, Sql Server jest całkiem dobry w efektywnym zarządzaniu planami zapytań.
Matthew Abbott
2

Zaznaczanie jest równie wydajne (pod względem szybkości), jeśli używasz * lub kolumn.

Różnica dotyczy pamięci, a nie szybkości. Po wybraniu kilku kolumn SQL Server musi przydzielić miejsce w pamięci, aby obsłużyć zapytanie, w tym wszystkie dane dla wszystkich żądanych kolumn, nawet jeśli używasz tylko jednej z nich.

Z punktu widzenia wydajności liczy się plan wykonania, który z kolei zależy w dużej mierze od Twojej klauzuli WHERE i liczby JOIN, OUTER JOIN itp.

W przypadku twojego pytania użyj SELECT *. Jeśli potrzebujesz wszystkich kolumn, nie ma różnicy w wydajności.

Jorge Córdoba
źródło
2

NIE jest szybsze użycie jawnych nazw pól w porównaniu z *, wtedy i tylko wtedy, gdy potrzebujesz danych dla wszystkich pól.

Oprogramowanie klienta nie powinno zależeć od kolejności zwracanych pól, więc to też bzdura.

I jest możliwe (choć mało prawdopodobne), że musisz pobrać wszystkie pola za pomocą *, ponieważ nie wiesz jeszcze, jakie pola istnieją (pomyśl o bardzo dynamicznej strukturze bazy danych).

Inną wadą używania jawnych nazw pól jest to, że jeśli jest ich wiele i są długie, to utrudnia to odczytanie kodu i / lub dziennika zapytań.

Dlatego zasada powinna brzmieć: jeśli potrzebujesz wszystkich pól, użyj *, jeśli potrzebujesz tylko podzbioru, nazwij je jawnie.

user9385
źródło
2

Wynik jest zbyt duży. Generowanie i wysyłanie wyniku z silnika SQL do klienta jest powolne.

Strona klienta, będąc ogólnym środowiskiem programistycznym, nie jest i nie powinna być zaprojektowana do filtrowania i przetwarzania wyników (np. Klauzula WHERE, klauzula ORDER), ponieważ liczba wierszy może być ogromna (np. Dziesiątki milionów wierszy).

kennytm
źródło
Więc gdybyś musiał faktycznie użyć wszystkich różnych kolumn, byłoby dobrze ... a jeśli twoja baza danych i aplikacja ponownie znajdują się na tym samym serwerze, nie robi to dużej różnicy?
Ankur
@Ankur: Nawet na tym samym serwerze przesyłanie danych przez interfejs bazy danych kosztuje.
kennytm
2

Nazwanie każdej kolumny, którą spodziewasz się uzyskać w aplikacji, zapewnia również, że aplikacja nie zepsuje się, jeśli ktoś zmieni tabelę, o ile kolumny są nadal obecne (w dowolnej kolejności).

Don
źródło
1

To zależy od wersji twojego serwera DB, ale nowoczesne wersje SQL mogą buforować plan w obie strony. Powiedziałbym, że wybierz wszystko, co jest najbardziej możliwe do utrzymania dzięki kodowi dostępu do danych.

Keith
źródło
1

Jednym z powodów, dla których lepiej jest dokładnie określić, które kolumny mają być, są możliwe przyszłe zmiany w strukturze tabeli.

Jeśli wczytujesz dane ręcznie, używając podejścia opartego na indeksach, aby wypełnić strukturę danych wynikami zapytania, to w przyszłości po dodaniu / usunięciu kolumny będziesz mieć bóle głowy, próbując dowiedzieć się, co poszło nie tak.

Jeśli chodzi o to, co jest szybsze, zwrócę się do innych za ich wiedzę.

dpollock
źródło
1

Jak w przypadku większości problemów, zależy to od tego, co chcesz osiągnąć. Jeśli chcesz utworzyć siatkę bazy danych, która będzie zezwalać na wszystkie kolumny w dowolnej tabeli, odpowiedzią jest „Wybierz *”. Jeśli jednak będziesz potrzebować tylko niektórych kolumn, a dodawanie lub usuwanie kolumn z zapytania odbywa się rzadko, określ je indywidualnie.

Zależy to również od ilości danych, które chcesz przesłać z serwera. Jeśli jedna z kolumn jest zdefiniowana jako notatka, grafika, blob itp. I nie potrzebujesz tej kolumny, lepiej nie używaj opcji „Wybierz *”, bo otrzymasz całą masę danych, których nie potrzebujesz chcesz, a Twoja wydajność może ucierpieć.

znak
źródło
1

Aby dodać do tego, co powiedzieli wszyscy inni, jeśli wszystkie wybrane przez Ciebie kolumny są uwzględnione w indeksie, zestaw wyników zostanie pobrany z indeksu zamiast wyszukiwać dodatkowe dane z SQL.

Mikrofon
źródło
1

SELECT * jest konieczne, jeśli chce się uzyskać metadane, takie jak liczba kolumn.

Mark Etable
źródło
1

Co powiedzieli wszyscy powyżej, a ponadto:

Jeśli dążysz do czytelnego, możliwego do utrzymania kodu, zrób coś takiego:

SELECT foo, bar FROM widżety;

jest natychmiast czytelny i pokazuje zamiar. Jeśli zadzwonisz, wiesz, co otrzymujesz. Jeśli widżety mają tylko kolumny foo i bar, to wybranie * oznacza, że ​​nadal musisz pomyśleć o tym, co otrzymujesz, potwierdzić, że kolejność jest poprawnie zmapowana itp. Jeśli jednak widżety mają więcej kolumn, ale interesuje Cię tylko foo i bar, kod staje się nieczytelny, gdy pytasz o symbol wieloznaczny, a następnie używasz tylko części zwróconych.

Faisal
źródło
1

Pamiętaj, że jeśli z definicji masz sprzężenie wewnętrzne, nie potrzebujesz wszystkich kolumn, ponieważ dane w kolumnach sprzężenia są powtarzane.

To nie jest tak, że wyświetlanie kolumn na serwerze SQl jest trudne lub nawet czasochłonne. Po prostu przeciągasz je z przeglądarki obiektów (możesz pobrać wszystko za jednym razem, przeciągając z kolumn słów). Aby na stałe obniżyć wydajność systemu (ponieważ może to zmniejszyć użycie indeksów i dlatego, że wysyłanie niepotrzebnych danych przez sieć jest kosztowne) i zwiększyć prawdopodobieństwo, że wystąpią nieoczekiwane problemy podczas zmiany bazy danych (czasami dodawane są kolumny, które na przykład nie chcesz, aby użytkownik widział), aby zaoszczędzić mniej niż minutę czasu programowania, jest krótkowzroczne i nieprofesjonalne.

HLGEM
źródło
1

Jeśli chodzi o wydajność, zauważyłem komentarze, że oba są równe. ale aspekt użyteczności jest kilka plusów i -ów

Kiedy używasz (wybierz *) w zapytaniu i jeśli ktoś zmieni tabelę i doda nowe pola, które nie są potrzebne w poprzednim zapytaniu, jest to niepotrzebny narzut. A co jeśli nowo dodane pole to blob lub pole obrazu ??? wtedy czas odpowiedzi na zapytanie będzie bardzo długi.

Z drugiej strony, jeśli używasz (wybierz kolumnę1, kolumnę2, ..) i jeśli tabela zostanie zmieniona i dodana nowe pola i jeśli te pola są potrzebne w zestawie wyników, zawsze musisz edytować zapytanie wybierające po zmianie tabeli.

Ale radzę zawsze używać select col1, col2, ... w zapytaniach i zmieniać zapytanie, jeśli tabela zostanie zmieniona później ...

Lahiru Cooray
źródło
0

Absolutnie zdefiniuj kolumny, które chcesz zaznaczyć za każdym razem. Nie ma powodu, aby tego nie robić, a poprawa wydajności jest tego warta.

Nigdy nie powinni dawać opcji „WYBIERZ *”

cazlab
źródło
0

Jeśli potrzebujesz każdej kolumny, po prostu użyj SELECT *, ale pamiętaj, że kolejność może się zmienić, więc gdy korzystasz z wyników, uzyskaj do nich dostęp według nazwy, a nie indeksu.

Zignorowałbym komentarze na temat tego, jak * musi przejść, aby uzyskać listę - istnieje prawdopodobieństwo, że analizowane są i sprawdzanie poprawności nazwanych kolumn jest równe czasowi przetwarzania, jeśli nie więcej. Nie optymalizuj przedwcześnie ;-)

DamienG
źródło
0

Jeśli chodzi o efektywność wykonania, nie widzę żadnej znaczącej różnicy. Ale dla wydajności programistów zapisałbym nazwy pól ponieważ

  • Znasz kolejność, jeśli chcesz indeksować według numeru lub jeśli Twój sterownik zachowuje się śmiesznie na wartościach typu blob i potrzebujesz określonej kolejności
  • Odczytujesz tylko te pola, których potrzebujesz, jeśli kiedykolwiek powinieneś dodać więcej pól
  • Otrzymujesz błąd sql, jeśli źle wpiszesz lub zmienisz nazwę pola, a nie pusta wartość z zestawu rekordów / wiersza
  • Możesz lepiej przeczytać, co się dzieje.
Erik
źródło
0

hej, bądź praktyczny. użyj select * podczas tworzenia prototypów i wybierz określone kolumny podczas wdrażania i wdrażania. z punktu widzenia planu wykonania oba są stosunkowo identyczne w nowoczesnych systemach. jednak wybranie określonych kolumn ogranicza ilość danych, które muszą zostać pobrane z dysku, zapisane w pamięci i przesłane przez sieć.

ostatecznie najlepszym planem jest wybranie określonych kolumn.

siculars
źródło