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

PEMBARUAN MySQL:5 Tip Teratas untuk Pengembang T-SQL

Apakah Anda menambahkan MySQL ke daftar keahlian database Anda? Maka pernyataan MySQL UPDATE adalah salah satu perintah yang perlu Anda pelajari.

Kami melanjutkan perjalanan kami ke MySQL dari sudut pandang SQL Server. Ini dimulai dengan CREATE TABLE, diikuti oleh INSERT, dan yang terbaru adalah tentang DELETE. Hari ini, UPDATE adalah titik fokus kami.

Perbedaannya halus dan mudah dipelajari. Tetapi seperti di artikel sebelumnya, tujuan kami adalah membuat Anda aktif dan berjalan dengan cepat. Namun sebelum kita melanjutkan, mari kita perjelas item ini:

  • Contoh yang digunakan di sini dijalankan di MySQL 8.0.23 menggunakan mesin penyimpanan InnoDB.
  • Kami menggunakan SQL Server 2019.

Siapkan Data Sampel

Kami tidak dapat melanjutkan tanpa data sampel. Saya ingin menempatkan pengembang T-SQL di rumah dalam latihan ini. Jadi, mari impor beberapa tabel yang sudah dikenal ke dalam AdventureWorks contoh database dari SQL Server:

  • Produk
  • SalesOrderHeader
  • Detail PesananPenjualan

Untuk mengimpor tabel ini ke MySQL, saya menggunakan dbForge Studio untuk MySQL. Berikut langkah-langkahnya:

  1. Buat database baru bernama adventureworks2019 .
  2. Klik kanan adventureworks2019 dan pilih Alat .
  3. Pilih Impor Data . Jendela baru akan muncul.
  4. Pilih ODBC . Anda perlu membuat DSN Pengguna untuk terhubung ke SQL Server Anda dan AdventureWorks basis data.
  5. Klik Berikutnya .
  6. Pilih tabel yang perlu Anda impor, koneksi MySQL, dan database target (adventureworks2019 ).
  7. Klik Berikutnya .
  8. Ubah pengaturan kolom. Anda juga dapat melihat data sampel. Anda dapat melewati ini dengan mengeklik Berikutnya atau ubah setelan sesuai keinginan Anda.
  9. Klik Impor .
  10. Impor tabel berikutnya dengan mengikuti petunjuk di layar yang sama.
  11. Klik Selesai .

Setelah mengimpor tabel ini, Anda sekarang siap untuk contoh dalam artikel ini. Jadi, mari kita mulai.

1. Dasar-dasar Sintaks

Sintaks pernyataan MySQL UPDATE seperti ini:

UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET assignment_list
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

Saya hampir bisa mendengar Anda setelah membaca sintaks:LOW PRIORITY, IGNORE, ORDER BY, dan LIMIT tidak cocok! Mari kita mulai berdiskusi dari atas.

Pertama, LOW_PRIORITY adalah kata kunci asing bagi kami karena SQL Server tidak mendukungnya. Ini opsional, tetapi jika Anda menyertakannya, pembaruan akan tertunda hingga semua klien lain tidak membaca tabel.

Kata kunci alien lainnya adalah IGNORE. Ini juga opsional, tetapi jika Anda memasukkannya dan terjadi duplikat, kesalahan tidak akan muncul. Untuk kesalahan yang tidak dapat diabaikan lainnya, lihat tautan ini.

Kemudian, ORDER BY. Kami tahu untuk apa. Tapi coba di SQL Server Management Studio dan garis berlekuk-lekuk akan muncul di bawah kata kunci.

Akhirnya, BATAS. Ini sama dengan TOP di SQL Server. Lebih banyak tentang ini dan ORDER BY di bagian selanjutnya.

Ini adalah perbedaan yang jelas. Baca lebih lanjut di 2 subbagian berikutnya.

MySQL UPDATE Kolom Tunggal

Memperbarui satu kolom hampir serupa. Jadi, contoh di bawah ini akan menghasilkan hasil yang sama dari kedua platform database. Namun, perhatikan bahwa alih-alih backtick, SQL Server menggunakan tanda kurung siku.

-- MySQL UPDATE single column
UPDATE `production.product`
SET ReorderPoint = 650
WHERE ProductID = 316;

Berikut sintaks T-SQL yang setara:

-- T-SQL UPDATE single column
UPDATE [Production].[Product]
SET ReorderPoint = 650
WHERE ProductID = 316;

Nilai yang ditetapkan ke kolom dapat berupa ekspresi nilai tunggal apa pun selama tipe yang dikembalikan sama dengan tipe data kolom.

MySQL UPDATE Beberapa Kolom

Memperbarui banyak kolom juga hampir mirip dengan T-SQL. Ini contohnya:

UPDATE `production.product`
SET ReorderPoint = 650, SafetyStockLevel = 1200
WHERE ProductID = 316;

Untuk memperbarui beberapa kolom, cukup pisahkan pasangan nilai kolom dengan koma. Sekali lagi, satu-satunya perbedaan di sini adalah backtick.

Sejauh ini, ini semua adalah pembaruan tabel tunggal. Mari beralih ke MySQL UPDATE dari tabel lain.

2. PEMBARUAN MySQL dengan GABUNG

Ada perbedaan kecil yang akan Anda lihat saat memperbarui tabel dengan gabungan. Cara terbaik untuk menunjukkannya adalah melalui contoh penggunaan 3 tabel.

UPDATE `sales.salesorderdetail` sod
INNER JOIN `sales.salesorderheader` soh ON sod.SalesOrderID = soh.SalesOrderID
INNER JOIN `production.product` p ON sod.ProductID = p.ProductID
set UnitPrice = p.ListPrice
WHERE p.ProductID = 758
AND soh.OrderDate = '2012-04-30';

Perhatikan bahwa beberapa klausa disusun secara berbeda jika dibandingkan dengan SQL Server. Gabungan muncul terlebih dahulu sebelum klausa SET. Tidak ada klausa FROM juga. Seperti yang Anda harapkan, SQL Server Management Studio akan menempatkan garis berlekuk-lekuk untuk sintaks yang menyinggung. Lihat ini dan sintaks T-SQL yang benar pada Gambar 1 di bawah ini.

Sebelum update, nilai harga satuan adalah 874.7940 seperti yang terlihat pada Gambar 2.

Setelah pembaruan, UnitPrice diperbarui dari Produk tabel ListPrice . Lihat Gambar 3.

Selain INNER JOIN, Anda dapat menggunakan LEFT atau RIGHT JOIN tergantung kebutuhan Anda.

3. PEMBARUAN MySQL dengan Subquery

Anda dapat menggunakan pernyataan MySQL UPDATE dari tabel lain menggunakan subquery. Kueri dengan gabungan di bagian sebelumnya dapat ditulis ulang menggunakan subkueri. Hasilnya akan sama. Ini dia:

UPDATE `sales.salesorderdetail` sod
INNER JOIN `sales.salesorderheader` soh ON sod.SalesOrderID = soh.SalesOrderID
SET sod.UnitPrice = (select ListPrice from `production.product` WHERE ProductID = 758)
WHERE sod.ProductID = 758
AND soh.OrderDate = '2012-04-30';

Pendekatannya berbeda, tetapi hasilnya sama seperti pada Gambar 3. Namun, perhatikan bahwa subquery yang digunakan untuk memperbarui kolom harus mengembalikan 1 nilai.

Ada cara lain untuk mengekspresikan pernyataan MySQL UPDATE ini.

4. PEMBARUAN MySQL dengan CTE

Common Table Expressions (CTE) didukung di MySQL dan SQL Server. Jika Anda tidak terbiasa dengan CTE, lihat artikel sebelumnya.

Sekarang, inilah pernyataan yang setara dengan CTE yang digunakan.

WITH priceIncrease AS
(
  SELECT soh.SalesOrderID, p.ProductID, p.ListPrice
  FROM `sales.salesorderdetail` sod
  INNER JOIN `sales.salesorderheader` soh ON sod.SalesOrderID = soh.SalesOrderID
  INNER JOIN `production.product` p ON sod.ProductID = p.ProductID
  WHERE p.ProductID = 758
  AND soh.OrderDate = '2012-04-30'
)
UPDATE `sales.salesorderdetail` s
INNER JOIN priceIncrease pi ON s.SalesOrderID = pi.SalesOrderID AND s.ProductID = pi.ProductID
SET s.UnitPrice = pi.ListPrice

SQL Server mendukung konsep yang sama, tetapi tanpa backticks. Hasilnya akan sama seperti pada Gambar 3.

Anda mungkin bertanya, mana dari 3 pendekatan yang lebih baik? Kami akan membandingkan kinerja mereka lebih lanjut.

5. PEMBARUAN MySQL dengan LIMIT

MySQL UPDATE dapat membatasi jumlah baris yang akan diperbarui dengan kata kunci LIMIT. Misalkan kita ingin memperbarui 5 catatan di Produk meja. Kita dapat mengungkapkan pernyataan seperti ini:

UPDATE `production.product` p
SET p.StandardCost = p.StandardCost + 10, p.ListPrice = p.ListPrice + 10
ORDER BY p.ProductID
LIMIT 5;

Ini akan mengurutkan catatan berdasarkan ProductID , lalu perbarui 5 catatan pertama. Itu berhenti setelah catatan ke-5.

Rekanan SQL Server dari LIMIT adalah TOP. Namun, Anda tidak bisa hanya mengubah kata kunci LIMIT ke TOP dan berharap itu akan berfungsi di SQL Server. Inilah versi modifikasi di T-SQL yang akan memberikan hasil yang sama:

UPDATE Production.Product
SET StandardCost += 10, ListPrice += 10
WHERE ProductID IN (SELECT TOP 5 ProductID 
		    FROM Production.Product 
		    ORDER BY ProductID)

Logikanya agak berbeda. Ini memperbarui Biaya Standar dan HargaDaftar kolom berdasarkan ID Produk yang ditemukan di subkueri. Subquery, di sisi lain, mengembalikan 5 catatan pertama dari Produk tabel diurutkan berdasarkan ProductID .

Meskipun TOP juga didukung di T-SQL UPDATE, ORDER BY tidak. Jadi, menggunakan TOP dengan UPDATE akan mengubah catatan acak. Sintaks di atas berlaku untuk record terurut dengan TOP.

Kinerja UPDATE MySQL

Sebelumnya, kami memiliki pernyataan UPDATE dengan hasil yang sama meskipun kami menggunakan metode yang berbeda. Kami menggunakan JOIN, subquery, dan CTE. Manakah dari mereka yang akan berkinerja terbaik?

Ada juga rencana eksekusi di MySQL menggunakan kata kunci EXPLAIN. Sintaksnya seperti ini:

EXPLAIN [FORMAT=JSON]
<SQL statement>

Tanpa format JSON, Anda memiliki informasi dasar seperti tabel, kunci indeks yang digunakan, dan baris yang dipindai. Ketika format JSON ditentukan, Anda memiliki informasi yang lebih detail. dbForge Studio untuk MySQL menyertakan Query Profiler selain hasil EXPLAIN. MySQL Workbench menyertakan Visual EXPLAIN di mana Anda dapat melihat tampilan grafis dari rencana berdasarkan EXPLAIN FORMAT=JSON.

Sekarang setelah kita mengetahui pernyataan baris perintah dan alat grafis, bagaimana kita dapat menggunakannya untuk membandingkan metode yang berbeda?

Sebelum kita melanjutkan, izinkan saya jujur. Kemahiran saya dalam SQL Server lebih tinggi daripada di MySQL. Saya mungkin melewatkan sesuatu di sepanjang jalan atau salah. Anda dapat mengisi kekosongan di bagian Komentar nanti.

Membedah EXPLAIN Hasil UPDATE dengan JOIN

Pertama kali saya menjalankan pernyataan MySQL UPDATE dengan JOIN, butuh 11,3 detik untuk 24 baris diperbarui. Luar biasa, bukan?

Inilah yang terjadi seperti yang terlihat di dbForge Studio. Lihat Gambar 4 di bawah ini.

Apa yang ditunjukkan Gambar 4 kepada kita?

  1. 3 alias tabel yang digunakan ada di sana. Ketiganya memiliki tipe akses ALL. Artinya MySQL menggunakan Table Scan untuk semua 3.
  2. Lihat kunci kolom. Tidak ada yang ditampilkan di ketiga tabel, artinya tidak ada kunci indeks yang digunakan. Ini mendukung poin Pemindaian Tabel sebelumnya.
  3. Akhirnya, baris kolom. Ini memberi tahu berapa banyak baris yang menurut MySQL harus dipindai untuk mencapai hasil akhir. Untuk 24 baris yang diperbarui, ribuan baris dipindai untuk SalesOrderHeader dan Detail Pesanan Penjualan . Sementara itu, semua baris Produk tabel dipindai.

Aku menggaruk kepalaku setelah mengetahui ini. Saya menyadari bahwa ketika saya mengimpor tabel dari SQL Server, hanya struktur tabel dan data yang diimpor, bukan indeks .

Jadi, saya membuat indeks dan kunci utama yang sesuai di dbForge Studio. Inilah yang saya buat:

  • Saya membuat ProductID di Produk tabel sebagai kunci utama.
  • Saya juga menambahkan SalesOrderID sebagai kunci utama di SalesOrderHeader meja. Kemudian, saya membuat indeks untuk OrderDate juga.
  • Akhirnya saya membuat SalesOrderDetailID di SalesOrderDetail tabel kunci utama. Saya juga menambahkan indeks untuk SalesOrderID dan IDProduk kolom tabel ini.

Setelah ini, saya membuat rencana eksekusi baru untuk kueri yang sama untuk melihat peningkatannya. Hasilnya?

PENINGKATAN KECEPATAN SETELAH MENAMBAHKAN INDEKS

Waktu eksekusi berkurang dari 11,3 detik menjadi 0,019 detik. Sangat keren!

Mari kita periksa paket baru menggunakan dbForge Studio pada Gambar 5 di bawah ini.

Apa yang ditunjukkan oleh Gambar 5 kepada kita?

  • Akses jenis dari 3 tabel diubah. 2 nilai yang harus dihindari di sini adalah ALL dan INDEX, terutama pada tabel besar. ALL adalah Pemindaian Tabel dan INDEX adalah Pemindaian Indeks.
  • Kunci kolom sekarang termasuk indeks yang digunakan. Ini bagus. Semua indeks yang ditambahkan telah digunakan.
  • Baris kolom sekarang menunjukkan angka yang lebih kecil. Indeks yang ditambahkan mengurangi banyak I/O pada kueri kami.

Untuk informasi lebih lanjut tentang detail dan nilai EXPLAIN, periksa dokumentasi resmi ini.

Tapi bagaimana ini dibandingkan dengan MySQL UPDATE dengan subquery?

Membedah EXPLAIN Hasil UPDATE dengan Subquery

Kueri sebelumnya untuk memperbarui UnitPrice kolom memiliki alternatif kueri lain, yaitu menggunakan subkueri. Bagaimana perbandingannya dengan JOIN? Lihat Gambar 6 di bawah ini.

Gambar 6 menunjukkan:

  • Nilai kolom tipe, kunci, dan baris sama dibandingkan dengan menggunakan JOIN. Ini logis karena seharusnya memiliki hasil yang sama.
  • Waktu eksekusi sedikit lebih cepat. Ini tidak akan terjadi setiap saat. Itu tergantung pada sumber daya yang tersedia saat ini. Perbedaan kecepatan juga dapat diabaikan. Anda tidak akan merasakannya sama sekali.

Cara lain adalah menggunakan EXPLAIN FORMAT=JSON untuk mendapatkan informasi lebih lanjut tentang rencana tersebut. Setelah diperiksa, nilai kueri biaya (84,79) dan info biaya adalah sama.

Sekarang, mari kita bandingkan dengan MySQL UPDATE dengan CTE.

Membedah EXPLAIN Hasil UPDATE dengan CTE

Menggunakan CTE sebagai dasar untuk memperbarui UnitPrice kolom seperti memiliki tabel sementara terlebih dahulu dan kemudian menggabungkan tabel sementara ke SalesOrderDetails . Pada pandangan pertama, ini mungkin terlihat seperti itu bukan pilihan yang baik dibandingkan dengan dua yang pertama. Tetapi ini menunjukkan kepada kita bahwa dimungkinkan untuk memiliki pembaruan di MySQL menggunakan CTE. Ini bisa menjadi pilihan yang baik dalam situasi lain. Bagaimanapun, mari kita JELASKAN hasil untuk pendekatan ini.

Jika Anda tidak memiliki dbForge Studio untuk MySQL, Anda dapat mencoba menghasilkan hasil EXPLAIN menggunakan perintah di editor lain. Ini contohnya:

EXPLAIN
WITH priceIncrease AS
(
  SELECT soh.SalesOrderID, p.ProductID, p.ListPrice
  FROM `sales.salesorderdetail` sod
  INNER JOIN `sales.salesorderheader` soh ON sod.SalesOrderID = soh.SalesOrderID
  INNER JOIN `production.product` p ON sod.ProductID = p.ProductID
  WHERE p.ProductID = 758
  AND soh.OrderDate = '2012-04-30'
)
UPDATE `sales.salesorderdetail` s
INNER JOIN priceIncrease pi ON s.SalesOrderID = pi.SalesOrderID AND s.ProductID = pi.ProductID
SET s.UnitPrice = pi.ListPrice

Hasilnya ada pada Gambar 7 di bawah ini.

Gambar 7 menunjukkan:

  • 4 tabel digunakan sebagai pengganti 3. Penggunaan pertama SalesOrderDetail ada di CTE dan kemudian di pernyataan UPDATE.
  • Lebih banyak tabel berarti lebih banyak baris dibandingkan dengan 2 pendekatan sebelumnya.

Anehnya, ini berjalan pada 0,015 detik (tidak ditunjukkan pada gambar). Hal yang sama dengan menggunakan subquery. Namun, itu tidak akan terjadi setiap saat. Itu tergantung pada sumber daya sistem yang tersedia pada saat eksekusi.

Total biaya kueri adalah 166,69. Ini lebih tinggi dari 2 pendekatan sebelumnya. Semakin rendah biaya kueri, semakin baik performa dari waktu ke waktu.

Bawa Pulang

Kami mempelajari lebih dalam perbedaan antara pernyataan UPDATE MySQL dan SQL Server. Kami telah mempelajari cara melakukannya saat memperbarui

  • satu kolom
  • beberapa kolom
  • tabel dengan gabungan
  • kolom menggunakan subkueri
  • tabel dengan CTE
  • dengan LIMIT

Dalam postingan ini, Anda juga telah melihat sekilas tentang EXPLAIN dan cara menggunakannya untuk membandingkan berbagai pendekatan UPDATE.

Saya harap ini dapat membantu Anda saat Anda mempelajari MySQL yang berasal dari SQL Server. Jika Anda menyukai posting ini, silakan bagikan di platform media sosial pilihan Anda. Dan jika ada yang kurang, beri tahu kami di bagian Komentar.

Selamat membuat kode!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL Bagaimana Anda INSERT INTO tabel dengan subquery SELECT mengembalikan beberapa baris?

  2. Apa efek menggunakan susunan biner?

  3. Mencocokkan semua nilai dalam klausa IN

  4. pendekatan yang lebih baik daripada menyimpan kata sandi mysql dalam teks biasa di file konfigurasi?

  5. Apakah mungkin untuk mengeksekusi string di MySQL?