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 * from
Anda 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