Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Haruskah saya menggunakan fungsi GABUNG atau menjalankan beberapa kueri dalam struktur loop?

Tak satu pun dari dua solusi yang diusulkan mungkin optimal, NAMUN solusi 1 TIDAK DAPAT DIPREDIKSI dan dengan demikian SANGAT CACAT!

Salah satu hal pertama yang Anda pelajari ketika berurusan dengan database besar adalah bahwa 'cara terbaik' untuk melakukan kueri sering kali bergantung pada faktor (disebut sebagai meta-data) dalam database:

  • Ada berapa baris.
  • Berapa banyak tabel yang Anda kueri.
  • Ukuran setiap baris.

Karena itu, tidak mungkin ada solusi peluru perak untuk masalah Anda. Basis data Anda tidak sama dengan basis data saya, Anda perlu membandingkan pengoptimalan yang berbeda jika Anda membutuhkan kinerja terbaik yang tersedia.

Anda mungkin akan menemukan bahwa menerapkan &membangun indeks yang benar (dan memahami implementasi asli dari indeks di MySQL) di database Anda melakukan lebih banyak hal untuk Anda.

Ada beberapa aturan emas dengan kueri yang seharusnya jarang dilanggar:

  • Jangan lakukan dalam struktur loop . Meskipun sering kali menggoda, biaya untuk membuat koneksi, mengeksekusi kueri, dan mendapatkan respons tinggi.
  • Hindari SELECT * kecuali diperlukan . Memilih lebih banyak kolom akan meningkatkan overhead operasi SQL Anda secara signifikan.
  • Ketahui indeks Anda . Gunakan EXPLAIN fitur sehingga Anda dapat melihat indeks mana yang digunakan, mengoptimalkan kueri Anda untuk menggunakan apa yang tersedia, dan membuat yang baru.

Karena itu, dari keduanya saya akan memilih kueri kedua (menggantikan SELECT * hanya dengan kolom yang Anda inginkan), tetapi mungkin ada cara yang lebih baik untuk menyusun kueri jika Anda punya waktu untuk mengoptimalkannya.

Namun, kecepatan seharusnya TIDAK menjadi satu-satunya pertimbangan Anda dalam hal ini, ada alasan BESAR untuk tidak menggunakan saran satu:

PREDIKTABILITAS:mengapa kunci baca adalah hal yang baik

Salah satu jawaban lain menunjukkan bahwa tabel terkunci untuk waktu yang lama adalah hal yang buruk, dan oleh karena itu solusi multi-kueri itu baik.

Saya berpendapat bahwa ini tidak mungkin jauh dari kebenaran . Bahkan, saya berpendapat bahwa dalam banyak kasus prediktabilitas menjalankan SELECT . penguncian tunggal kueri adalah argumen yang lebih besar UNTUK menjalankan kueri itu daripada manfaat pengoptimalan &kecepatan.

Pertama-tama, ketika kita menjalankan SELECT kueri (hanya baca) pada database MyISAM atau InnoDB (sistem default untuk MySQL), yang terjadi adalah tabel dikunci untuk dibaca. Ini mencegah operasi MENULIS apa pun terjadi di atas meja hingga kunci baca diserahkan (baik SELECT kami kueri selesai atau gagal). SELECT Other lainnya kueri tidak terpengaruh, jadi jika Anda menjalankan aplikasi multi-utas, kueri akan terus berfungsi.

Penundaan ini adalah hal yang BAIK. Mengapa, Anda mungkin bertanya? Integritas data relasional.

Mari kita ambil contoh:kami menjalankan operasi untuk mendapatkan daftar item yang saat ini ada di inventaris sekelompok pengguna di sebuah game, jadi kami melakukan ini untuk bergabung:

SELECT * FROM `users` JOIN `items` ON `users`.`id`=`items`.`inventory_id` WHERE `users`.`logged_in` = 1;

Apa yang terjadi jika, selama operasi kueri ini, pengguna memperdagangkan item ke pengguna lain? Dengan menggunakan kueri ini, kami melihat status permainan seperti saat kami memulai kueri:item ada sekali, dalam inventaris pengguna yang memilikinya sebelum kami menjalankan kueri.

Tapi, apa yang terjadi jika kita menjalankannya dalam satu lingkaran?

Bergantung pada apakah pengguna memperdagangkannya sebelum atau setelah kami membaca detailnya, dan dalam urutan apa kami membaca inventaris kedua pemain, ada empat kemungkinan:

  1. Item dapat ditampilkan di inventaris pengguna pertama (pindai pengguna B -> pindai pengguna A -> item yang diperdagangkan ATAU pindai pengguna B -> pindai pengguna A -> item yang diperdagangkan).
  2. Item dapat ditampilkan di inventaris pengguna kedua (item diperdagangkan -> pindai pengguna A -> pindai pengguna B ATAU item yang diperdagangkan -> pindai pengguna B -> pindai pengguna A).
  3. Item dapat ditampilkan di keduanya inventaris (pindai pengguna A -> item yang diperdagangkan -> pindai pengguna B).
  4. Item tidak dapat ditampilkan di tidak keduanya inventaris pengguna (pindai pengguna B -> item yang diperdagangkan -> pindai pengguna A).

Artinya kami tidak akan dapat memprediksi hasil kueri atau memastikan integritas relasional .

Jika Anda berencana untuk memberikan $5.000 kepada orang dengan ID item 1000000 pada tengah malam hari Selasa, saya harap Anda memiliki $10k. Jika program Anda bergantung pada item unik yang unik saat snapshot diambil, Anda mungkin akan memunculkan pengecualian dengan jenis kueri ini.

Penguncian bagus karena meningkatkan prediktabilitas dan melindungi integritas hasil.

Catatan:Anda dapat memaksa loop untuk mengunci dengan transaksi , tetapi akan tetap lebih lambat.

Oh, dan akhirnya, GUNAKAN PERNYATAAN YANG DIPERSIAPKAN!

Anda seharusnya tidak pernah memiliki pernyataan yang terlihat seperti ini:

mysqli_query("SELECT * FROM Table2 WHERE ColumnAId=" . $row['ColumnAId'], $con);

mysqli memiliki dukungan untuk pernyataan yang disiapkan . Baca tentang mereka dan gunakan, mereka akan membantu Anda menghindari sesuatu yang buruk terjadi pada database Anda .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pilih dengan beberapa tag

  2. Bagaimana cara memilih subkategori dari kategori yang dipilih menggunakan fungsi bersarang di PHP?

  3. Laravel 4 tidak dapat menjalankan seluruh kueri RAW

  4. Baca file teks dan transfer konten ke database mysql

  5. mengirim sms massal berhenti di tengah