Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

3 Tips Teratas yang Perlu Anda Ketahui untuk Menulis Tampilan SQL Lebih Cepat

Teman atau musuh? Tampilan SQL Server telah menjadi bahan perdebatan sengit ketika saya masih di tahun pertama saya menggunakan SQL Server. Mereka mengatakan itu buruk karena lambat. Tapi bagaimana dengan hari ini?

Apakah Anda berada di kapal yang sama seperti saya bertahun-tahun yang lalu? Kemudian, bergabunglah dengan saya dalam perjalanan ini untuk mengungkap masalah sebenarnya tentang tampilan SQL sehingga Anda dapat menulisnya secepat mungkin.

Tampilan SQL adalah tabel virtual. Rekaman dalam tampilan adalah hasil kueri di dalamnya. Setiap kali tabel dasar yang digunakan dalam tampilan diperbarui, itu juga memperbarui tampilan. Anda juga bisa INSERT, UPDATE, dan DELETE record dalam tampilan sebagai tabel dalam beberapa kasus. Meskipun saya sendiri belum mencobanya.

Sama halnya dengan tabel, Anda dapat MENCIPTAKAN, MENGUBAH, atau MENGHAPUS tampilan. Anda bahkan dapat membuat indeks, dengan beberapa batasan.

Perhatikan bahwa saya menggunakan SQL Server 2019 dalam kode sampel.

1. Mengetahui Penggunaan Tampilan SQL yang Benar dan Tidak Tepat

Pertama, dasar-dasarnya.

Untuk apa tampilan SQL?

Ini sangat penting. Jika Anda menggunakannya sebagai palu ke obeng, lupakan tampilan SQL yang lebih cepat. Pertama, mari kita ingat penggunaan yang tepat:

  • Untuk memfokuskan, menyederhanakan, dan menyesuaikan persepsi yang dimiliki setiap pengguna terhadap database.
  • Untuk mengizinkan pengguna mengakses satu-satunya informasi yang perlu mereka lihat untuk alasan keamanan.
  • Untuk memberikan kompatibilitas mundur ke tabel lama atau skema lama agar tidak merusak aplikasi yang bergantung. Ini bersifat sementara sampai semua perubahan yang diperlukan selesai.
  • Untuk mempartisi data yang berasal dari server yang berbeda. Oleh karena itu, mereka muncul seolah-olah mereka adalah satu tabel dari satu server atau instance.

Bagaimana TIDAK menggunakan tampilan SQL Server?

  • Gunakan kembali tampilan di tampilan lain yang akan digunakan kembali di tampilan lain. Singkatnya, pandangan yang sangat bersarang. Penggunaan kembali kode memiliki beberapa kelemahan dalam kasus ini.
  • Menghemat penekanan tombol. Ini terkait dengan yang pertama, yang mengurangi tekanan jari dan tampaknya mempercepat pengkodean.

Penggunaan tampilan yang tidak tepat, jika diizinkan, akan mengaburkan alasan sebenarnya mengapa Anda membuat tampilan. Seperti yang akan Anda lihat nanti, manfaat sebenarnya lebih besar daripada manfaat yang dirasakan dari penggunaan yang tidak tepat.

Contoh

Mari kita periksa contoh dari Microsoft. vKaryawan lihat dari AdventureWorks . Ini kodenya:

-- Employee names and basic contact information
CREATE VIEW [HumanResources].[vEmployee] 
AS 
SELECT 
    e.[BusinessEntityID]
    ,p.[Title]
    ,p.[FirstName]
    ,p.[MiddleName]
    ,p.[LastName]
    ,p.[Suffix]
    ,e.[JobTitle]  
    ,pp.[PhoneNumber]
    ,pnt.[Name] AS [PhoneNumberType]
    ,ea.[EmailAddress]
    ,p.[EmailPromotion]
    ,a.[AddressLine1]
    ,a.[AddressLine2]
    ,a.[City]
    ,sp.[Name] AS [StateProvinceName] 
    ,a.[PostalCode]
    ,cr.[Name] AS [CountryRegionName] 
    ,p.[AdditionalContactInfo]
FROM [HumanResources].[Employee] e
    INNER JOIN [Person].[Person] p
 ON p.[BusinessEntityID] = e.[BusinessEntityID]
    INNER JOIN [Person].[BusinessEntityAddress] bea 
        ON bea.[BusinessEntityID] = e.[BusinessEntityID] 
    INNER JOIN [Person].[Address] a 
        ON a.[AddressID] = bea.[AddressID]
    INNER JOIN [Person].[StateProvince] sp 
        ON sp.[StateProvinceID] = a.[StateProvinceID]
    INNER JOIN [Person].[CountryRegion] cr 
        ON cr.[CountryRegionCode] = sp.[CountryRegionCode]
    LEFT OUTER JOIN [Person].[PersonPhone] pp
        ON pp.BusinessEntityID = p.[BusinessEntityID]
    LEFT OUTER JOIN [Person].[PhoneNumberType] pnt
        ON pp.[PhoneNumberTypeID] = pnt.[PhoneNumberTypeID]
    LEFT OUTER JOIN [Person].[EmailAddress] ea
        ON p.[BusinessEntityID] = ea.[BusinessEntityID];
GO

Tujuan dari pandangan ini berfokus pada informasi dasar karyawan. Jika dibutuhkan oleh staf sumber daya manusia, dapat ditampilkan di halaman web. Apakah itu digunakan kembali di tampilan lain?

Coba ini:

  1. Di SQL Server Management Studio , cari AdventureWorks basis data.
  2. Luaskan folder Tampilan dan cari [Sumber Daya Manusia].[vKaryawan].
  3. Klik kanan dan pilih Lihat Dependensi .

Jika Anda melihat tampilan lain tergantung pada tampilan ini, yang kemudian bergantung pada tampilan yang berbeda, Microsoft memberi kami contoh yang buruk. Tapi kemudian, tidak ada dependensi tampilan lain.

Mari kita lanjutkan ke yang berikutnya.

2. Membongkar Mitos pada Tampilan SQL

Saat SQL Server memproses PILIH dari tampilan , itu mengevaluasi kode dalam tampilan SEBELUM berurusan dengan klausa WHERE atau gabungan apa pun di kueri luar. Dengan lebih banyak tabel bergabung, ini akan menjadi lambat dibandingkan dengan PILIH dari tabel dasar dengan hasil yang sama.

Setidaknya, itulah yang saya diberitahu ketika saya mulai menggunakan SQL. Entah itu mitos atau bukan, hanya ada satu cara untuk mengetahuinya. Mari kita beralih ke contoh praktis.

Cara Kerja Tampilan SQL

Microsoft tidak membiarkan kami dalam kegelapan untuk berdebat tanpa henti. Kami memiliki alat untuk melihat cara kerja kueri, seperti STATISTICS IO dan Rencana Eksekusi Aktual . Kami akan menggunakan ini dalam semua contoh kami. Mari kita dapatkan yang pertama.

USE AdventureWorks
GO

SELECT * FROM HumanResources.vEmployee e
WHERE e.BusinessEntityID = 105

Untuk melihat apa yang terjadi saat SQL Server memproses tampilan, mari kita periksa Rencana Eksekusi Aktual pada Gambar 1. Kami membandingkannya dengan kode CREATE VIEW untuk vEmployee di bagian sebelumnya.

Seperti yang Anda lihat, node pertama yang diproses oleh SQL Server adalah node yang menggunakan INNER JOIN. Kemudian, ia melanjutkan untuk memproses LEFT OUTER JOIN.

Karena kita tidak dapat melihat simpul Filter di mana pun untuk klausa WHERE, ia harus berada di salah satu simpul tersebut. Jika Anda memeriksa semua properti node, Anda akan melihat klausa WHERE diproses di tabel Employee. Saya telah memasukkannya ke dalam kotak pada Gambar 1. Untuk membuktikan bahwa itu ada, lihat Gambar 2 untuk Properti dari simpul itu:

Analisis

Jadi, miliki pernyataan SELECT di vEmployee view telah dievaluasi atau diproses SEBELUM klausa WHERE diterapkan? Rencana Eksekusi menunjukkan bahwa tidak. Jika ya, itu akan muncul paling dekat dengan simpul SELECT.

Apa yang saya diberitahu adalah sebuah mitos. Saya menghindari sesuatu yang baik karena kesalahpahaman tentang penggunaan tampilan SQL yang tepat.

Sekarang kita tahu bagaimana SQL Server memproses SELECT dari tampilan , pertanyaannya tetap:Apakah lebih lambat daripada tidak menggunakan tampilan?

SELECT FROM View vs. SELECT FROM Base Tables – Mana yang Akan Berjalan Lebih Cepat?

Pertama, kita perlu mengekstrak pernyataan SELECT di dalam vEmployee melihat dan menghasilkan hasil yang sama seperti yang kita miliki saat menggunakan tampilan. Kode di bawah ini menunjukkan klausa WHERE yang sama:

USE AdventureWorks
GO

-- SELECT FROM a view
SELECT * FROM HumanResources.vEmployee e
WHERE e.BusinessEntityID = 105

-- SELECT FROM Base Tables
SELECT 
    e.[BusinessEntityID]
    ,p.[Title]
    ,p.[FirstName]
    ,p.[MiddleName]
    ,p.[LastName]
    ,p.[Suffix]
    ,e.[JobTitle]  
    ,pp.[PhoneNumber]
    ,pnt.[Name] AS [PhoneNumberType]
    ,ea.[EmailAddress]
    ,p.[EmailPromotion]
    ,a.[AddressLine1]
    ,a.[AddressLine2]
    ,a.[City]
    ,sp.[Name] AS [StateProvinceName] 
    ,a.[PostalCode]
    ,cr.[Name] AS [CountryRegionName] 
    ,p.[AdditionalContactInfo]
FROM [HumanResources].[Employee] e
    INNER JOIN [Person].[Person] p
	ON p.[BusinessEntityID] = e.[BusinessEntityID]
    INNER JOIN [Person].[BusinessEntityAddress] bea 
        ON bea.[BusinessEntityID] = e.[BusinessEntityID] 
    INNER JOIN [Person].[Address] a 
        ON a.[AddressID] = bea.[AddressID]
    INNER JOIN [Person].[StateProvince] sp 
        ON sp.[StateProvinceID] = a.[StateProvinceID]
    INNER JOIN [Person].[CountryRegion] cr 
        ON cr.[CountryRegionCode] = sp.[CountryRegionCode]
    LEFT OUTER JOIN [Person].[PersonPhone] pp
        ON pp.BusinessEntityID = p.[BusinessEntityID]
    LEFT OUTER JOIN [Person].[PhoneNumberType] pnt
        ON pp.[PhoneNumberTypeID] = pnt.[PhoneNumberTypeID]
    LEFT OUTER JOIN [Person].[EmailAddress] ea
        ON p.[BusinessEntityID] = ea.[BusinessEntityID]
WHERE e.BusinessEntityID = 105

Kemudian, kami memeriksa STATISTICS IO dan melakukan Bandingkan Showplan . Berapa banyak sumber daya yang dibutuhkan kueri dari tampilan dibandingkan dengan kueri dari tabel dasar? Lihat Gambar 3.

Di sini, kueri dari tampilan atau tabel dasar akan menggunakan pembacaan logis yang sama. Keduanya menggunakan halaman 19 * 8KB. Berdasarkan ini, ini adalah dasi pada siapa yang lebih cepat. Dengan kata lain, menggunakan tampilan tidak akan mengganggu kinerja. Mari kita bandingkan Rencana Eksekusi Aktual keduanya menggunakan Bandingkan Showplan :

Apakah Anda melihat bagian diagram yang diarsir? Bagaimana dengan QueryPlanHash keduanya? Karena kedua kueri memiliki QueryPlanHash yang sama dan operasi yang sama, baik tampilan atau tabel dasar akan diproses sama oleh SQL Server .

Pembacaan logis yang sama dan rencana sampel yang sama memberi tahu kita bahwa keduanya akan melakukan hal yang sama. Dengan demikian, memiliki pembacaan logis yang tinggi akan membuat kueri Anda berjalan lambat apakah Anda menggunakan tampilan atau tidak. Mengetahui fakta ini akan membantu Anda memperbaiki masalah dan membuat tampilan Anda berjalan lebih cepat.

Sayangnya, ada kabar buruk.

Menggabungkan Tampilan SQL ke Tabel

Apa yang Anda lihat sebelumnya adalah PILIH dari tampilan tanpa gabungan di dalamnya. Namun, bagaimana jika Anda menggabungkan tabel ke tampilan?

Mari kita tinjau contoh lain. Kali ini, kami menggunakan vSalesPerson lihat di AdventureWorks – daftar tenaga penjualan dengan informasi kontak dan kuota penjualan. Sekali lagi, kami membandingkan pernyataan dengan SELECT dari tabel dasar:

-- get the total sales orders for each salesperson
-- using the view joined with SalesOrderHeader
SELECT 
 sp.FirstName
,sp.MiddleName
,sp.LastName
,SUM(soh.TotalDue) AS TotalSalesOrders
FROM Sales.vSalesPerson sp
INNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID = soh.SalesPersonID
GROUP BY sp.LastName, sp.MiddleName, sp.FirstName

-- using base tables
SELECT
 p.FirstName
,p.MiddleName
,p.LastName
,SUM(soh.TotalDue) AS TotalSalesOrders
FROM sales.SalesPerson sp
INNER JOIN Person.Person p ON sp.BusinessEntityID = P.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID = soh.SalesPersonID
GROUP BY p.LastName, p.MiddleName, p.FirstName 

Jika menurut Anda juga akan sama, periksa STATISTICS IO:

Terkejut? Bergabung dengan vSalesPerson lihat dengan SalesOrderHeader tabel membutuhkan sumber daya yang luar biasa (28.240 x 8KB) dibandingkan dengan hanya menggunakan tabel dasar (774 x 8KB). Perhatikan juga bahwa itu termasuk beberapa tabel yang tidak kita butuhkan (tabel di dalam kotak merah). Apalagi pembacaan logis yang lebih tinggi di SalesOrderHeader saat menggunakan tampilan.

Tapi itu tidak berakhir di situ.

Rencana Eksekusi Aktual Mengungkap Lebih Banyak

Perhatikan Rencana Eksekusi Aktual dari kueri ke tabel dasar:

Ilustrasi tersebut tampaknya menunjukkan Rencana Eksekusi yang cukup normal. Tapi lihat yang dengan pemandangan:

Rencana eksekusi pada Gambar 7 bertepatan dengan STATISTICS IO pada Gambar 5. Kita dapat melihat tabel yang tidak kita perlukan dari tampilan. Ada juga Pencarian Kunci simpul dengan perkiraan baris yang lebih dari seribu catatan daripada baris sebenarnya. Akhirnya, peringatan di node SELECT juga muncul. Apa itu?

Apa itu Berlebihan peringatan di simpul SELECT?

Hibah Berlebihan terjadi ketika memori yang digunakan maksimum terlalu kecil dibandingkan dengan memori yang diberikan. Dalam hal ini, 1024KB diberikan, tetapi hanya 16KB yang digunakan.

Memory Grant adalah perkiraan jumlah memori dalam KB yang diperlukan untuk menjalankan paket.

Ini bisa menjadi perkiraan yang salah di Pencarian Kunci node dan/atau penyertaan tabel yang tidak kami perlukan dalam rencana yang menyebabkan hal ini. Juga, terlalu banyak memori yang diberikan dapat menyebabkan pemblokiran. Sisanya 1008KB bisa berguna untuk operasi lain.

Akhirnya, terjadi kesalahan saat Anda menggabungkan tampilan dengan tabel. Kami tidak harus berurusan dengan masalah ini jika kami membuat kueri dari tabel dasar.

Bawa Pulang

Itu adalah penjelasan yang panjang. Namun, kita tahu bahwa tampilan tidak dievaluasi atau diproses SEBELUM klausa WHERE atau gabungan dalam kueri luar dievaluasi. Kami juga membuktikan bahwa keduanya akan melakukan hal yang sama.

Di sisi lain, ada kasus ketika kita menggabungkan tampilan ke tabel. Ini menggunakan gabungan tabel yang tidak kita perlukan dari tampilan. Mereka tidak terlihat oleh kita kecuali kita memeriksa STATISTIK IO dan Rencana Eksekusi Aktual. Itu semua dapat merusak kinerja, dan masalah mungkin muncul entah dari mana.

Oleh karena itu:

  • Kita harus tahu bagaimana kueri, termasuk tampilan, bekerja dari dalam.
  • STATISTICS IO dan Rencana Eksekusi Aktual akan mengungkapkan cara kerja kueri dan tampilan.
  • Kita tidak bisa begitu saja menggabungkan tampilan ke tabel dan menggunakannya kembali secara sembarangan. Selalu periksa STATISTIK IO dan Rencana Eksekusi Aktual! Alih-alih menggunakan kembali tampilan dan menumpuknya untuk produktivitas pengkodean yang “meningkatkan”, saya menggunakan IntelliSense dan alat penyelesaian kode seperti SQL Complete.

Kami kemudian dapat memastikan untuk tidak menulis tampilan yang akan memiliki hasil yang benar tetapi berjalan seperti siput.

3. Coba Tampilan Terindeks

Tampilan yang diindeks adalah apa yang tersirat dari namanya. Ini dapat memberikan peningkatan kinerja pada pernyataan SELECT. Namun seperti indeks tabel, ini dapat memengaruhi kinerja jika tabel dasar berukuran besar dan terus diperbarui.

Untuk melihat bagaimana tampilan yang diindeks dapat meningkatkan kinerja kueri, mari kita periksa vStateProvinceCountryRegion lihat di AdventureWorks . Tampilan diindeks pada StateProvinceID dan CountryRegionCode . Ini adalah indeks yang berkerumun dan unik.

Mari kita bandingkan STATISTICS IO dari tampilan yang tidak memiliki indeks dan memiliki indeks. Dengan ini, kita mengetahui berapa banyak halaman 8KB yang akan dibaca oleh SQL Server kita:

Gambar menunjukkan bahwa memiliki indeks di vStateProvinceCountryRegion view mengurangi pembacaan logis hingga setengahnya. Ini adalah peningkatan 50% dibandingkan dengan tidak memiliki indeks.

Itu bagus untuk didengar.

Namun, sekali lagi, jangan menambahkan indeks ke tampilan Anda secara sembarangan. Selain memiliki daftar panjang aturan ketat untuk memiliki 1 unik, indeks berkerumun, itu dapat merusak kinerja, seperti menambahkan indeks ke tabel dengan riang. Juga, periksa STATISTICS IO jika ada penurunan pembacaan logis setelah menambahkan indeks.

Bawa Pulang

Seperti yang telah kita lihat dalam contoh kita, tampilan yang diindeks dapat meningkatkan kinerja tampilan SQL.

Kiat BONUS

Sama seperti kueri lainnya, tampilan SQL akan berjalan cepat jika:

  • Statistik diperbarui
  • Indeks yang hilang ditambahkan
  • Indeks didefrag
  • Indeks menggunakan FILLFACTOR yang tepat

Kesimpulan

Apakah tampilan SQL baik atau buruk?

Tampilan SQL bagus jika kita menulisnya dengan benar dan memeriksa untuk melihat bagaimana mereka akan diproses. Kami memiliki alat seperti STATISTICS IO dan Rencana Eksekusi Aktual – gunakan! Tampilan yang diindeks juga dapat meningkatkan performa.

Suka postingan ini? Silakan berbagi cinta di platform media sosial favorit 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. Cara Menggabungkan Beberapa (3+) Tabel dalam Satu Pernyataan

  2. Perancangan Model Data Sistem Pemesanan Kamar Hotel

  3. Aturan Codd dalam SQL

  4. Dasar-dasar ekspresi tabel, Bagian 4 – Tabel turunan, pertimbangan pengoptimalan, lanjutan

  5. Menghubungkan SAS JMP ke Salesforce.com