Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

pilih penurunan kinerja pernyataan saat menggunakan DISTINCT dengan parameter

Masalahnya bukan karena DISTINCT menyebabkan penurunan kinerja dengan parameter, tetapi sisa kueri tidak dioptimalkan dalam kueri berparameter karena pengoptimal tidak hanya akan mengoptimalkan semua gabungan menggunakan [email protected] _ADMINISTRATOR menyukainya hanya dengan 1=1. Itu tidak akan mengoptimalkan gabungan tanpa berbeda karena perlu mengembalikan duplikat berdasarkan hasil gabungan.

Mengapa? Karena rencana eksekusi membuang semua gabungan akan menjadi tidak valid untuk nilai apa pun selain @IS_ADMINISTRATOR =1. Itu tidak akan pernah menghasilkan rencana itu terlepas dari apakah Anda sedang menyimpan rencana atau tidak.

Ini berfungsi sebaik kueri yang tidak berparameter di server 2008 saya:

-- PARAMETRIZED QUERY

declare @IS_ADMINISTRATOR int
declare @User_ID int
set @IS_ADMINISTRATOR = 1 -- 1 for administrator 0 for normal
set @User_ID = 50

IF 1 = @IS_ADMINISTRATOR 
BEGIN
SELECT DISTINCT -- PLEASE REMEMBER DISTINCT MAKES THE DIFFERENCE!!!
  DOC.DOCUMENT_ID
FROM
  DOCUMENTS DOC LEFT OUTER JOIN
  FOLDERS FOL ON FOL.FOLDER_ID = DOC.FOLDER_ID LEFT OUTER JOIN
  ROLES ROL ON (FOL.FOLDER_ID = ROL.FOLDER_ID)   
WHERE
  1 = 1
END
ELSE 
BEGIN
SELECT DISTINCT -- PLEASE REMEMBER DISTINCT MAKES THE DIFFERENCE!!!
  DOC.DOCUMENT_ID
FROM
  DOCUMENTS DOC LEFT OUTER JOIN
  FOLDERS FOL ON FOL.FOLDER_ID = DOC.FOLDER_ID LEFT OUTER JOIN
  ROLES ROL ON (FOL.FOLDER_ID = ROL.FOLDER_ID)   
WHERE
  ROL.USER_ID = @USER_ID
END

Yang jelas dari paket kueri yang saya lihat menjalankan contoh Anda adalah @IS_ADMINISTRATOR = 1 tidak dioptimalkan sama dengan 1=1 . Dalam contoh non-parameter Anda, GABUNG sepenuhnya dioptimalkan, dan hanya mengembalikan setiap id dalam tabel DOKUMEN (sangat sederhana).

Ada juga pengoptimalan berbeda yang hilang saat @IS_ADMINISTRATOR <> 1 . Misalnya, LEFT OUTER JOIN S secara otomatis diubah menjadi INNER JOIN s tanpa bahwa OR klausa, tetapi dibiarkan apa adanya dengan itu atau klausa.

Lihat juga jawaban ini:SQL LIKE % UNTUK INTEGER untuk alternatif SQL dinamis.

Tentu saja, ini tidak benar-benar menjelaskan perbedaan kinerja dalam pertanyaan awal Anda, karena Anda tidak memiliki OR di sana. Saya berasumsi bahwa itu adalah kekhilafan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SSIS 2008 - Dapatkan Tanggal Saat Ini dalam Variabel

  2. Parsing string yang dipisahkan koma untuk membuat IN Daftar string dalam klausa Where

  3. Mengapa menggunakan kunci utama bukan nol di TSQL?

  4. Berikan Akses Pengguna msdb ke Profil Email Database di SQL Server (T-SQL)

  5. Bagaimana cara mengembalikan ke database yang berbeda di SQL Server?