Ada banyak komentar setelah posting saya minggu lalu tentang pemisahan string. Saya pikir inti dari artikel itu tidak sejelas yang seharusnya:menghabiskan banyak waktu dan upaya untuk mencoba "menyempurnakan" fungsi pemisahan yang lambat secara inheren berdasarkan T-SQL tidak akan bermanfaat. Sejak itu saya telah mengumpulkan versi terbaru dari fungsi pemisahan string Jeff Moden, dan membandingkannya dengan yang lain:
ALTER FUNCTION [dbo].[DelimitedSplitN4K] (@pString NVARCHAR(4000), @pDelimiter NCHAR(1)) RETURNS TABLE WITH SCHEMABINDING AS RETURN WITH E1(N) AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ), E2(N) AS (SELECT 1 FROM E1 a, E1 b), E4(N) AS (SELECT 1 FROM E2 a, E2 b), cteTally(N) AS (SELECT TOP (ISNULL(DATALENGTH(@pString)/2,0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4), cteStart(N1) AS (SELECT 1 UNION ALL SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter ), cteLen(N1,L1) AS(SELECT s.N1, ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,4000) FROM cteStart s ) SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1), Item = SUBSTRING(@pString, l.N1, l.L1) FROM cteLen l; GO
(Satu-satunya perubahan yang saya buat:Saya telah memformatnya untuk ditampilkan, dan saya telah menghapus komentarnya. Anda dapat mengambil sumber aslinya di sini.)
Saya harus melakukan beberapa penyesuaian pada pengujian saya untuk mewakili fungsi Jeff secara adil. Yang paling penting:Saya harus membuang semua sampel yang melibatkan string> 4.000 karakter. Jadi saya mengubah string 5.000 karakter di tabel dbo.strings menjadi 4.000 karakter, dan hanya fokus pada tiga skenario non-MAX pertama (menjaga hasil sebelumnya untuk dua yang pertama, dan menjalankan tes ketiga lagi untuk yang baru panjang string 4.000 karakter). Saya juga menghapus tabel Numbers dari semua kecuali satu tes, karena jelas bahwa kinerja di sana selalu lebih buruk dengan faktor setidaknya 10. Bagan berikut menunjukkan kinerja fungsi di masing-masing dari empat tes, sekali lagi rata-rata lebih dari 10 proses dan selalu dengan cache dingin dan buffer bersih.
Jadi, inilah metode pilihan saya yang sedikit direvisi, untuk setiap jenis tugas:
Anda akan melihat bahwa CLR tetap menjadi metode pilihan saya, kecuali dalam satu kasus di mana pemisahan tidak masuk akal. Dan dalam kasus di mana CLR bukan merupakan pilihan, metode XML dan CTE umumnya lebih efisien, kecuali dalam kasus pemisahan variabel tunggal, di mana fungsi Jeff mungkin merupakan pilihan terbaik. Tetapi mengingat bahwa saya mungkin perlu mendukung lebih dari 4.000 karakter, solusi tabel Numbers mungkin akan kembali ke daftar saya dalam situasi tertentu di mana saya tidak diizinkan menggunakan CLR.
Saya berjanji bahwa posting saya berikutnya yang melibatkan daftar tidak akan berbicara tentang pemisahan sama sekali, melalui T-SQL atau CLR, dan akan menunjukkan cara menyederhanakan masalah ini terlepas dari tipe datanya.
Sebagai tambahan, saya melihat komentar ini di salah satu versi fungsi Jeff yang diposting di komentar:Saya juga berterima kasih kepada siapa pun yang menulis artikel pertama yang pernah saya lihat di "tabel angka" yang terletak di URL berikut dan kepada Adam Machanic untuk menuntun saya ke sana bertahun-tahun yang lalu.http://web.archive.org/web/20150411042510/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an -tabel-angka-bantu.html
Artikel itu saya tulis pada tahun 2004. Jadi siapapun yang menambahkan komentar pada fungsi tersebut, dipersilakan. :-)