Mengapa "Pilih * dari tabel" dianggap praktik buruk

96

Kemarin saya berdiskusi dengan programmer "hobi" (saya sendiri adalah programmer profesional). Kami menemukan beberapa karyanya, dan dia berkata dia selalu menanyakan semua kolom dalam database-nya (bahkan pada / di server produksi / kode).

Saya mencoba meyakinkan dia untuk tidak melakukannya, tetapi belum begitu berhasil. Menurut pendapat saya seorang programmer hanya harus menanyakan apa yang sebenarnya dibutuhkan demi "kecantikan", efisiensi dan lalu lintas. Apakah saya salah dengan pandangan saya?

baconing itu
sumber
1
Saya akan mengatakan itu cos bagaimana jika isi tabel berubah? menambah / menghapus kolom? Anda masih memilih * .. jadi Anda akan kehilangan barang atau menarik lebih banyak data dari yang Anda butuhkan.
JF it
2
@ JFit Itu bagian dari itu, tetapi jauh dari keseluruhan cerita.
jwenting
6
Dan alasan bagus di sini, Mengapa pilih * dianggap berbahaya?
Ellie Kesselman
@gnat dapatkah sebuah pertanyaan dianggap sebagai duplikat dari pertanyaan tertutup? (Yaitu karena yang tertutup tidak benar-benar cocok di tempat pertama)
gbjbaanb

Jawaban:

67

Pikirkan tentang apa yang Anda dapatkan kembali, dan bagaimana Anda mengikat mereka ke variabel dalam kode Anda.

Sekarang pikirkan apa yang terjadi ketika seseorang memperbarui skema tabel untuk menambahkan (atau menghapus) kolom, bahkan yang tidak Anda gunakan secara langsung.

Menggunakan pilih * saat Anda mengetik kueri dengan tangan baik-baik saja, bukan saat Anda menulis kueri untuk kode.

gbjbaanb
sumber
8
Kinerja, beban jaringan, dll. Jauh lebih penting daripada kenyamanan mendapatkan kembali kolom dalam urutan dan dengan nama yang Anda inginkan.
jwenting
21
@jwenting kok? kinerja lebih penting daripada kebenaran? Lagi pula, saya tidak melihat bahwa "pilih *" berkinerja lebih baik daripada hanya memilih kolom yang Anda inginkan.
gbjbaanb
9
@Bratch, dalam lingkungan produksi kehidupan nyata, Anda mungkin memiliki ratusan aplikasi menggunakan tabel yang sama dan tidak mungkin semua aplikasi itu dapat dikelola dengan baik. Anda benar dalam sentimen, tetapi secara praktis, argumen itu gagal hanya karena kenyataan bekerja di copmanies. Perubahan skema ke tabel aktif terjadi setiap saat.
user1068
18
Saya tidak mengerti maksud dari jawaban ini. Jika Anda menambahkan kolom ke tabel, baik SELECT * dan SELECT [Kolom] akan berfungsi, satu-satunya perbedaan adalah jika kode perlu mengikat ke kolom baru, SELECT [Kolom] perlu dimodifikasi sedangkan SELECT * tidak akan. Jika sebuah kolom dihapus dari sebuah tabel, SELECT * akan rusak pada titik pengikatan, sedangkan SELECT [Kolom] akan pecah ketika kueri dieksekusi. Menurut saya SELECT * adalah opsi yang lebih fleksibel karena setiap perubahan pada tabel hanya akan membutuhkan perubahan pada binding. Apakah saya melewatkan sesuatu?
TallGuy
11
@ gbjbaanb lalu akses kolom dengan nama. Hal lain jelas bodoh kecuali Anda menentukan urutan kolom dalam kueri.
user253751
179

Perubahan Skema

  • Ambil berdasarkan pesanan --- Jika kode mengambil kolom # sebagai cara untuk mendapatkan data, perubahan skema akan menyebabkan nomor kolom menyesuaikan kembali. Ini akan mengacaukan aplikasi dan hal-hal buruk akan terjadi.
  • Ambil menurut nama --- Jika kode tersebut mengambil kolom dengan nama seperti foo, dan tabel lain dalam kueri menambahkan kolom foo, cara ini ditangani dapat menyebabkan masalah ketika mencoba untuk mendapatkan kolom yang tepat foo .

Either way, perubahan skema dapat menyebabkan masalah dengan ekstraksi data.

Lebih lanjut pertimbangkan jika kolom yang sedang digunakan dihapus dari tabel. The select * from ...masih bekerja tapi kesalahan ketika mencoba untuk menarik data dari hasil set. Jika kolom ditentukan dalam kueri, kueri akan keluar sebagai gantinya memberikan indikasi yang jelas tentang apa dan di mana masalahnya.

Overhead data

Beberapa kolom dapat memiliki sejumlah besar data yang terkait dengannya. Memilih kembali *akan menarik semua data. Yap, ini ada varchar(4096)pada 1000 baris yang telah Anda pilih untuk kembali memberi Anda kemungkinan tambahan 4 megabita data yang tidak Anda perlukan, tetapi dikirim melalui kabel.

Terkait dengan perubahan skema, varchar itu mungkin tidak ada di sana ketika Anda pertama kali membuat tabel, tetapi sekarang ada di sana.

Gagal menyampaikan maksud

Ketika Anda memilih kembali *dan mendapatkan 20 kolom tetapi hanya membutuhkan 2 kolom, Anda tidak menyampaikan maksud kode. Ketika melihat permintaan yang dilakukan select *seseorang tidak tahu apa bagian penting dari itu. Bisakah saya mengubah kueri untuk menggunakan paket lain ini untuk membuatnya lebih cepat dengan tidak menyertakan kolom ini? Saya tidak tahu karena maksud dari pengembalian kueri tidak jelas.


Mari kita lihat beberapa biola SQL yang mengeksplorasi perubahan skema sedikit lebih.

Pertama, basis data awal: http://sqlfiddle.com/#!2/a67dd/1

DDL:

create table one (oneid int, data int, twoid int);
create table two (twoid int, other int);

insert into one values (1, 42, 2);
insert into two values (2, 43);

SQL:

select * from one join two on (one.twoid = two.twoid);

Dan kolom Anda kembali adalah oneid=1, data=42, twoid=2, dan other=43.

Sekarang, apa yang terjadi jika saya menambahkan kolom ke tabel satu? http://sqlfiddle.com/#!2/cd0b0/1

alter table one add column other text;

update one set other = 'foo';

Dan hasil saya dari query yang sama seperti sebelumnya yang oneid=1, data=42, twoid=2, dan other=foo.

Perubahan pada salah satu tabel mengganggu nilai-nilai a select *dan tiba-tiba pengikatan 'lain' ke int akan menimbulkan kesalahan dan Anda tidak tahu mengapa.

Jika bukan pernyataan SQL Anda

select 
    one.oneid, one.data, two.twoid, two.other
from one join two on (one.twoid = two.twoid);

Perubahan ke tabel satu tidak akan mengganggu data Anda. Kueri itu menjalankan hal yang sama sebelum perubahan dan setelah perubahan.


Pengindeksan

Ketika Anda melakukan, select * fromAnda menarik semua baris dari semua tabel yang sesuai dengan kondisi. Bahkan meja Anda benar-benar tidak peduli. Meskipun ini berarti lebih banyak data yang ditransfer, ada masalah kinerja lain yang mengintai di stack.

Indeks. (terkait pada SO: Bagaimana cara menggunakan indeks dalam pernyataan pilih? )

Jika Anda menarik kembali banyak kolom, pengoptimal rencana basis data dapat mengabaikan menggunakan indeks karena Anda masih perlu mengambil semua kolom itu dan akan membutuhkan lebih banyak waktu untuk menggunakan indeks dan kemudian mengambil semua kolom dalam kueri daripada hanya untuk melakukan scan tabel lengkap.

Jika Anda hanya memilih, katakanlah, nama belakang pengguna (yang sering Anda lakukan dan memiliki indeks), basis data dapat melakukan pemindaian indeks saja (pemindaian indeks postgres wiki saja , pemindaian tabel lengkap mysql vs penuh pemindaian indeks , Pemindaian Hanya-Indeks: Menghindari Akses Tabel ).

Ada sedikit optimisasi tentang membaca hanya dari indeks jika memungkinkan. Informasi dapat ditarik lebih cepat pada setiap halaman indeks karena Anda juga menarik lebih sedikit - Anda tidak menarik semua kolom lain untuk select *. Mungkin saja pemindaian hanya indeks untuk mengembalikan hasil pada urutan 100x lebih cepat (sumber: Pilih * buruk ).

Ini tidak mengatakan bahwa pemindaian indeks lengkap sangat bagus, ini masih pemindaian penuh - tetapi lebih baik daripada pemindaian tabel penuh. Setelah Anda mulai mengejar semua cara yang select *menyakitkan kinerja Anda terus menemukan yang baru.

Bacaan terkait

Komunitas
sumber
2
@Tonny saya setuju - tetapi ketika saya menjawab (pertama) saya tidak pernah berpikir pertanyaan ini akan menghasilkan begitu banyak diskusi dan komentar! Jelas untuk menanyakan hanya untuk kolom bernama, bukan ?!
gbjbaanb
3
Memecah segala sesuatu dengan menambahkan kolom juga merupakan alasan bagus mengapa kode harus selalu mengakses kolom dalam datareader dengan nama bukan dengan ordinal kode-keras ...
Julia Hayward
1
@ gbjbaanb Ini untuk saya. Tetapi banyak orang datang untuk menulis query SQL tanpa latar belakang formal / pelatihan. Bagi mereka mungkin tidak jelas.
Tonny
1
@Aaronaught Saya sudah memperbaruinya dengan bit tambahan pada masalah pengindeksan. Apakah ada poin lain yang harus saya kemukakan untuk kesalahan select *?
3
Wow, jawaban yang diterima sangat buruk untuk benar-benar menjelaskan apa pun yang saya pilih. Kagum bahwa ini bukan jawaban yang diterima. +1.
Ben Lee
38

Kekhawatiran lain: jika itu adalah JOINkueri dan Anda mengambil hasil kueri ke dalam array asosiatif (seperti yang terjadi di PHP), itu rawan bug.

Masalahnya adalah itu

  1. jika tabel foomemiliki kolom iddanname
  2. jika tabel barmemiliki kolom iddan address,
  3. dan dalam kode yang Anda gunakan SELECT * FROM foo JOIN bar ON foo.id = bar.id

tebak apa yang terjadi ketika seseorang menambahkan kolom nameke bartabel.

Kode tiba-tiba akan berhenti berfungsi dengan baik, karena sekarang namekolom muncul di hasil dua kali dan jika Anda menyimpan hasilnya ke dalam array, data dari second name( bar.name) akan menimpa yang pertama name( foo.name)!

Ini adalah bug yang tidak menyenangkan karena sangat tidak jelas. Mungkin perlu beberapa saat untuk mencari tahu, dan tidak mungkin orang menambahkan kolom lain ke meja bisa mengantisipasi efek samping yang tidak diinginkan.

(Kisah nyata).

Jadi, jangan gunakan *, kendalikan kolom apa yang Anda ambil dan gunakan alias jika perlu.

Konrad Morawski
sumber
oke dalam hal ini (yang saya anggap agak langka) bisa jadi masalah besar. Tetapi Anda masih bisa menghindari (dan kebanyakan orang mungkin akan) melakukannya dengan menanyakan dengan wildcard dan hanya menambahkan alias untuk nama kolom yang sama.
baconing
4
Secara teori, tetapi jika Anda menggunakan wildcard untuk kenyamanan, Anda mengandalkannya untuk secara otomatis memberi Anda semua kolom yang ada dan tidak pernah repot-repot memperbarui kueri saat tabel bertambah. Jika Anda menentukan masing-masing dan setiap kolom, Anda terpaksa pergi ke permintaan untuk menambahkan satu lagi ke SELECTklausa Anda dan ini adalah saat Anda berharap menemukan nama itu tidak unik. BTW Saya tidak berpikir itu sangat langka dalam sistem dengan database besar. Seperti yang saya katakan, saya pernah menghabiskan beberapa jam berburu bug ini dalam bola kode PHP yang besar. Dan saya menemukan kasing lain sekarang: stackoverflow.com/q/17715049/168719
Konrad Morawski
3
Saya menghabiskan satu jam minggu lalu mencoba untuk mendapatkan ini melalui kepala konsultan. Dia seharusnya menjadi guru SQL ... Sigh ...
Tonny
22

Meminta setiap kolom mungkin benar-benar sah, dalam banyak kasus.

Selalu meminta setiap kolom tidak.

Ini lebih berfungsi untuk mesin basis data Anda, yang harus mematikan dan mencari-cari di sekitar metadata internal untuk mencari tahu kolom mana yang perlu ditangani sebelum dapat melanjutkan bisnis nyata untuk benar-benar mendapatkan data dan mengirimkannya kembali kepada Anda. OK, ini bukan overhead terbesar di dunia, tetapi katalog sistem bisa menjadi hambatan yang cukup besar.

Ini lebih berfungsi untuk jaringan Anda, karena Anda menarik kembali sejumlah bidang ketika Anda mungkin hanya menginginkan satu atau dua bidang. Jika seseorang [lain] pergi dan menambahkan beberapa lusin bidang tambahan, yang semuanya berisi potongan teks besar, throughput Anda tiba-tiba melewati lantai - tanpa alasan yang jelas. Ini menjadi lebih buruk jika klausa "di mana" Anda tidak terlalu bagus dan Anda menarik banyak baris juga - itu berpotensi banyak data yang menginjak jalannya di jaringan kepada Anda (yaitu akan lambat).

Ini lebih berfungsi untuk aplikasi Anda, harus menarik kembali dan menyimpan semua data tambahan ini yang sangat mungkin tidak peduli.

Anda menjalankan risiko kolom mengubah urutannya. OK, Anda tidak perlu khawatir tentang ini (dan Anda tidak akan melakukannya jika Anda hanya memilih kolom yang Anda butuhkan) tetapi, jika Anda mendapatkan semuanya sekaligus dan seseorang [lain] memutuskan untuk mengatur ulang urutan kolom dalam tabel , yang dibuat dengan hati-hati, ekspor CSV yang Anda berikan ke akun di aula tiba-tiba berubah menjadi pot - lagi, tanpa alasan yang jelas.

BTW, saya sudah mengatakan "seseorang [lain]" beberapa kali, di atas. Ingat bahwa database pada dasarnya multi-pengguna; Anda mungkin tidak memiliki kendali atas mereka yang Anda pikir Anda miliki.

Phill W.
sumber
3
Saya akan berpikir bahwa selalu meminta setiap kolom mungkin sah untuk hal-hal seperti fasilitas tampilan tabel schema-agnostik. Bukan situasi yang sangat umum, tetapi dalam konteks alat yang hanya digunakan secara internal, hal-hal seperti itu bisa berguna.
supercat
1
@supercat Itu hanya tentang kasus penggunaan HANYA valid untuk "SELECT *" yang bisa saya pikirkan. Dan bahkan kemudian saya lebih suka membatasi kueri menjadi "SELECT TOP 10 *" (dalam MS SQL) atau menambahkan "LIMIT 10" (mySQL) atau menambahkan "WHERE ROWNUM <= 10" (Oracle). Biasanya dalam hal ini lebih tentang "kolom apa yang ada dan beberapa sampel data" daripada konten lengkap.
Tonny
@Tonny: SQL Server mengubah skrip default mereka untuk menambahkan TOPbatasan; Saya tidak yakin seberapa penting itu jika kode dibaca sebanyak yang ingin ditampilkan dan kemudian membuang kueri. Saya pikir respons permintaan diproses agak malas, meskipun saya tidak tahu detailnya. Bagaimanapun, saya berpikir bahwa daripada mengatakannya "tidak sah", akan lebih baik untuk mengatakan "... sah dalam jumlah yang jauh lebih sedikit"; pada dasarnya, saya akan meringkas kasus-kasus yang sah sebagai kasus-kasus di mana pengguna akan memiliki ide yang lebih baik apa yang berarti daripada programmer.
supercat
@supercat saya bisa menyetujuinya. Dan saya sangat suka cara Anda memasukkannya ke dalam kalimat terakhir Anda. Saya harus ingat itu.
Tonny
11

Jawaban singkatnya adalah: itu tergantung pada database apa yang mereka gunakan. Relasional database dioptimalkan untuk mengekstraksi data yang Anda butuhkan dalam cepat, handal dan atom cara. Pada dataset besar dan pertanyaan kompleks, ini jauh lebih cepat dan mungkin lebih aman daripada SELECTing * dan melakukan yang setara dengan gabungan di sisi 'kode'. Toko-toko kunci mungkin tidak menerapkan fungsionalitas seperti itu, atau mungkin tidak cukup matang untuk digunakan dalam produksi.

Yang mengatakan, Anda masih dapat mengisi struktur data apa pun yang Anda gunakan dengan SELECT * dan mengerjakan sisanya dalam kode tetapi Anda akan menemukan hambatan kinerja jika Anda ingin skala.

Perbandingan terdekat adalah pengurutan data: Anda dapat menggunakan quicksort atau bubblesort dan hasilnya akan benar. Tetapi tidak akan dioptimalkan, dan pasti akan memiliki masalah ketika Anda memperkenalkan konkurensi dan perlu mengurutkan secara atom.

Tentu saja, lebih murah untuk menambahkan RAM dan CPU daripada berinvestasi pada seorang programmer yang dapat melakukan query SQL dan bahkan memiliki pemahaman yang kabur tentang apa itu JOIN.

lorenzog
sumber
Pelajari SQL! Itu tidak sulit. Ini adalah bahasa "asli" dari basis data jauh dan luas. Sangat kuat. Elegan. Itu telah teruji oleh waktu. Dan tidak ada cara Anda akan menulis bergabung di sisi "kode" yang lebih efisien daripada bergabung dalam database, kecuali jika Anda benar-benar tidak kompeten dalam melakukan bergabung SQL. Pertimbangkan itu untuk melakukan "penggabungan kode", Anda harus menarik semua data dari kedua tabel bahkan dalam gabungan 2 tabel sederhana. Atau apakah Anda menarik statistik indeks dan menggunakannya untuk memutuskan data tabel mana yang akan ditarik sebelum Anda bergabung? Tidak mengira begitu ... Belajarlah untuk menggunakan database dengan benar, orang-orang.
Craig
@Craig: SQL adalah umum di relasional database jauh dan luas. Itu jauh dari satu-satunya jenis DB, meskipun ... dan ada alasan pendekatan database yang lebih modern sering disebut NoSQL. : P Tidak ada yang saya tahu akan memanggil SQL "elegan" tanpa dosis ironi yang berat. Itu hanya menyedot kurang dari banyak alternatif, sejauh menyangkut basis data relasional.
cHao
@ cHao Saya sudah sangat sadar akan berbagai jenis database di luar sana selama beberapa dekade . Basis data Pick "nosql" telah ada selamanya. "NoSQL" bahkan bukan konsep baru. ORM juga telah ada selamanya, dan mereka selalu lambat. Lambat! = Bagus. Mengenai keanggunan (LINQ?), Anda tidak dapat meyakinkan saya bahwa ini masuk akal atau anggun untuk klausa di mana: Customer customer = this._db.Customers.Where( “it.ID = @ID”, new ObjectParameter( “ID”, id ) ).First();Lihat Time to Take Offense di halaman 2.
Craig
@Craig: Jangan mulai saya menggunakan ORM. Hampir setiap sistem di luar sana melakukannya dengan mengerikan, dan abstraksi bocor ke mana-mana. Itu karena catatan DB relasional bukan objek - paling-paling, itu adalah nyali bagian serial dari suatu objek. Tetapi untuk LINQ, Anda benar-benar ingin pergi ke sana? Setara SQLish adalah sesuatu seperti var cmd = db.CreateCommand(); cmd.CommandText = "SELECT TOP 1 * FROM Customers WHERE ID = @ID"; cmd.Parameters.AddWithValue("@ID", id); var result = cmd.ExecuteReader();.... dan kemudian lanjutkan untuk membuat Pelanggan dari setiap baris. LINQ mengalahkan celana itu.
cHao
@Craig: Memang, tidak seanggun mungkin. Tapi itu tidak akan seanggun yang saya inginkan sampai dapat mengubah kode .net ke SQL. :) Pada titik mana Anda bisa mengatakan var customer = _db.Customers.Where(it => it.id == id).First();.
cHao
8

IMO, ini tentang menjadi eksplisit vs implisit. Ketika saya menulis kode, saya ingin itu berfungsi karena saya membuatnya bekerja, bukan hanya karena semua bagian kebetulan ada di sana. Jika Anda meminta semua catatan dan kode Anda berfungsi, maka Anda akan cenderung untuk melanjutkan. Nanti jika sesuatu berubah dan sekarang kode Anda tidak berfungsi, akan sulit untuk men-debug banyak pertanyaan dan fungsi mencari nilai yang seharusnya ada di sana dan satu-satunya referensi nilai adalah *.

Juga dalam pendekatan N-tiered, masih lebih baik untuk mengisolasi gangguan skema database ke tingkat data. Jika tingkat data Anda melewati * ke logika bisnis dan kemungkinan besar pada tingkat presentasi, Anda memperluas cakupan debug Anda secara eksponensial.

zkent
sumber
3
Ini mungkin salah satu alasan terpenting di sini, dan hanya ada sebagian kecil suara. Pemeliharaan basis kode yang dikotori select *jauh lebih buruk!
Eamon Nerbonne
6

karena jika tabel mendapat kolom baru maka Anda mendapatkan semua itu bahkan ketika Anda tidak membutuhkannya. dengan varcharsini bisa menjadi banyak data tambahan yang perlu diajak bepergian dari DB

beberapa optimasi DB juga dapat mengekstrak catatan panjang tidak tetap ke file terpisah untuk mempercepat akses ke bagian panjang tetap, menggunakan pilih * mengalahkan tujuan dari itu

ratchet freak
sumber
1

Selain overhead, sesuatu yang ingin Anda hindari di tempat pertama, saya akan mengatakan bahwa sebagai seorang programmer Anda tidak bergantung pada urutan kolom yang ditentukan oleh administrator database. Anda memilih setiap kolom bahkan jika Anda membutuhkan semuanya.

dj bazzie wazzie
sumber
3
Setuju, meskipun saya juga merekomendasikan menarik nilai dari hasil yang ditetapkan oleh nama kolom dalam hal apa pun.
Rory Hunter
Diperbantukan, dibawa Gunakan nama kolom, jangan bergantung pada urutan kolom. Urutan kolom adalah ketergantungan rapuh. Nama harus (Anda harap) berasal dari beberapa upaya desain aktual, atau Anda secara eksplisit alias kolom komposit atau perhitungan atau nama kolom yang saling bertentangan dalam permintaan Anda, dan referensi alias eksplisit yang Anda tentukan. Tetapi mengandalkan pesanan cukup banyak hanya lakban dan doa ...
Craig
1

Saya tidak melihat alasan mengapa Anda tidak boleh menggunakan untuk tujuan membangun - mengambil semua kolom dari database. Saya melihat tiga kasus:

  1. Kolom ditambahkan dalam database dan Anda juga menginginkannya dalam kode. a) Dengan * akan gagal dengan pesan yang tepat. b) Tanpa * akan berfungsi, tetapi tidak akan melakukan apa yang Anda harapkan sangat buruk.

  2. Kolom ditambahkan dalam database dan Anda tidak menginginkannya dalam kode. a) Dengan * akan gagal; ini berarti * tidak lagi berlaku karena semantiknya berarti "mengambil semua". b) Tanpa * akan bekerja.

  3. Kolom dihapus Kode akan gagal baik.

Sekarang kasus yang paling umum adalah kasus 1 (karena Anda menggunakan * yang berarti semua yang paling Anda inginkan); tanpa * Anda dapat memiliki kode yang berfungsi dengan baik tetapi tidak melakukan apa yang diharapkan, jauh lebih buruk daripada yang gagal dengan pesan kesalahan yang tepat .

Saya tidak mempertimbangkan kode yang mengambil data kolom berdasarkan indeks kolom yang rawan kesalahan menurut saya. Jauh lebih logis untuk mengambilnya berdasarkan nama kolom.

m3th0dman
sumber
Premis Anda salah. Select *dimaksudkan lebih sebagai kenyamanan untuk permintaan ad-hoc, bukan untuk tujuan pengembangan aplikasi. Atau untuk digunakan dalam konstruksi statistik seperti select count(*)yang memungkinkan mesin kueri memutuskan apakah akan menggunakan indeks, indeks mana yang akan digunakan dan seterusnya dan Anda tidak mengembalikan data kolom yang sebenarnya. Atau untuk digunakan dalam klausa seperti where exists( select * from other_table where ... ), yang sekali lagi merupakan undangan ke mesin kueri untuk memilih jalur paling efisien sendiri dan subquery hanya digunakan untuk membatasi hasil dari kueri utama. Dll
Craig
@Craig Saya percaya setiap buku / tutorial tentang SQL mengatakan select *memiliki semantik untuk mengambil semua kolom; jika aplikasi Anda benar-benar membutuhkan ini, saya tidak melihat alasan mengapa tidak menggunakannya. Bisakah Anda menunjuk ke beberapa referensi (Oracle, IBM, Microsoft dll.) Yang menyebutkan tujuan yang select *dibangun bukan untuk mengambil semua kolom?
m3th0dman
Ya, tentu saja select *ada untuk mengambil semua kolom ... sebagai fitur kenyamanan, untuk query ad-hoc, bukan karena itu ide bagus dalam perangkat lunak produksi. Alasannya sudah tercakup dengan cukup baik dalam jawaban di halaman ini, itulah sebabnya saya tidak membuat jawaban terperinci saya sendiri: •) Masalah kinerja, berulang kali menyusun data melalui jaringan yang tidak pernah Anda gunakan, •) masalah dengan kolom alias, •) kegagalan optimisasi rencana permintaan (kegagalan untuk menggunakan indeks dalam beberapa kasus), •) server I / O yang tidak efisien dalam kasus di mana pemilihan terbatas hanya dapat menggunakan indeks, dll.
Craig
Mungkin ada kasus tepi di sini atau di sana yang membenarkan penggunaan select *dalam aplikasi produksi yang sebenarnya, tetapi sifat dari kasus tepi adalah bahwa itu bukan kasus umum . :-)
Craig
@Craig Alasannya adalah menentang mengambil semua kolom dari database tidak menentang menggunakan select *; apa yang saya katakan jika Anda benar-benar membutuhkan semua kolom, saya tidak melihat alasan mengapa Anda tidak boleh menggunakan select *; walaupun sedikit harus ada skenario di mana semua kolom dibutuhkan.
m3th0dman
1

Pikirkan seperti ini ... jika Anda kueri semua kolom dari tabel yang hanya memiliki beberapa string kecil atau bidang angka, total data itu 100 ribu. Latihan yang buruk, tapi itu akan berhasil. Sekarang tambahkan satu bidang yang menampung, katakanlah, gambar atau dokumen kata 10MB. sekarang kueri berkinerja cepat Anda segera dan secara misterius mulai berkinerja buruk, hanya karena bidang telah ditambahkan ke tabel ... Anda mungkin tidak memerlukan elemen data yang sangat besar, tetapi karena Anda telah melakukannya, Select * from TableAnda tetap mendapatkannya.

kevin mitchell
sumber
6
ini sepertinya hanya mengulangi poin yang sudah dibuat beberapa jam yang lalu di jawaban pertama dan di beberapa jawaban lainnya
Agas