it-swarm.asia

Manfaat Common Table Expression (CTE)?

Dari msdn :

Tidak seperti tabel turunan, CTE bisa menjadi rujukan sendiri dan dapat direferensikan beberapa kali dalam kueri yang sama.

Saya menggunakan CTE cukup banyak, tetapi saya tidak pernah berpikir mendalam tentang manfaat menggunakannya.

Jika saya mereferensikan CTE beberapa kali dalam permintaan yang sama:

  • Apakah ada manfaat kinerja?
  • Jika saya melakukan self join, apakah SQL Server akan memindai tabel target dua kali?
21
Royi Namir

Sebagai aturan, CTE tidak akan pernah meningkatkan kinerja .

CTE pada dasarnya adalah pandangan sekali pakai. Tidak ada statistik tambahan yang disimpan, tidak ada indeks, dll. Berfungsi sebagai singkatan untuk subquery.

Menurut pendapat saya mereka dapat digunakan dengan mudah MUDAH (saya melihat banyak kode yang digunakan terlalu berlebihan dalam pekerjaan saya). Beberapa jawaban bagus ada di sini, tetapi jika Anda perlu merujuk sesuatu lebih dari satu kali, atau lebih dari beberapa ratus ribu baris, tuliskan dalam #temp sebagai gantinya tabel dan indeks.

25
JNK

Satu tempat selain rekursi di mana saya menemukan CTE sangat berguna adalah ketika membuat kueri pelaporan yang kompleks. Saya menggunakan serangkaian CTE untuk mendapatkan potongan data yang saya butuhkan dan kemudian menggabungkannya di pilih terakhir. Saya menemukan mereka lebih mudah untuk mempertahankan daripada melakukan hal yang sama dengan banyak tabel turunan atau 20 bergabung dan saya menemukan bahwa saya dapat lebih yakin bahwa itu mengembalikan data yang benar tanpa efek dari beberapa catatan karena satu-banyak hubungan di semua bergabung berbeda. Biarkan saya memberi contoh cepat:

;WITH Conferences (Conference_id)
AS 
(select  m.Conference_id
FROM mydb.dbo.Conference m 
WHERE client_id = 10
    and Conference_id in 
            (select Conference_id from mydb.dbo.Expense 
            where amount <>0
            and amount is not null)
     )
--select * from Conferences
,MealEaters(NumberMealEaters, Conference_id, AttendeeType)
AS
(Select count(*) as NumberMealEaters, m.Conference_id,  AttendeeType 
from mydb.dbo.attendance ma 
join Conferences m on m.Conference_id = ma.Conference_id
where (ma.meals_consumed>0 or meals_consumed is null)and attended = 1
group by m.Conference_id)
--select * from MealEaters

,Expenses (Conference_id,expense_date, expenseDescription,  RecordIdentifier,amount)
AS
(select Conference_id,max(expense_date) as Expense_date, expenseDescription,  RecordIdentifier,sum(amount) as amount
    FROM
        (SELECT Conference_id,expense_date,  amount, RecordIdentifier
        FROM mydb.dbo.Expense
        WHERE  amount <> 0 
            and Conference_id IN 
            (SELECT  Conference_id
            FROM mydb.dbo.Conferences ) 
        group by Conference_id, RecordIdentifier) a
)
--select * from Expenses
Select m.Conference_id,me.NumberMealEaters, me.AttendeeType, e.expense_date,         e.RecordIdentifier,amount
from Conferences m
join mealeaters me on m.Conference_id = me.Conference_id
join expenses e on e.Conference_id = m.Conference_id

Jadi dengan memisahkan potongan informasi yang Anda inginkan, Anda dapat memeriksa setiap bagian secara terpisah (menggunakan pilihan yang dikomentari, dengan membatalkan komentar masing-masing secara individual dan hanya berjalan sejauh pilihan itu) dan jika Anda perlu melakukan perubahan pada biaya perhitungan (dalam contoh ini), lebih mudah ditemukan daripada ketika mereka dicampur bersama menjadi satu permintaan besar. Tentu saja pertanyaan pelaporan aktual yang saya gunakan untuk ini pada umumnya jauh lebih rumit daripada contohnya.

14
HLGEM

Seperti biasa itu tergantung tetapi ada kasus di mana kinerja sangat meningkat. Saya melihatnya dengan pernyataan INSERT INTO SELECT di mana Anda menggunakan CTE untuk pilih dan kemudian menggunakannya di INSERT INTO. Ini mungkin ada hubungannya dengan RCSI yang diaktifkan untuk database tetapi untuk saat-saat ketika sangat sedikit yang dipilih dapat membantu sedikit.

0
Ron S