Apakah Tampilan dioptimalkan ketika saya menambahkan klausa WHERE kepada mereka?

28

Apakah ada bedanya jika Anda memfilter Tampilan di dalam atau di luar Tampilan?

Misalnya, apakah ada perbedaan antara kedua pertanyaan ini?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Atau

SELECT Id
FROM MyView
WHERE SomeColumn = 1

Dan MyViewdidefinisikan sebagai

SELECT Id, SomeColumn
FROM MyTable

Dan apakah jawabannya berbeda jika tabel sumber terletak di Server Linked?

Saya bertanya karena saya harus meminta tabel besar (baris 44mil) dua kali dari server yang ditautkan, dan mendapatkan agregat hasil. Saya ingin tahu apakah saya harus membuat dua tampilan untuk mengakses data, satu untuk setiap permintaan, atau jika saya bisa lolos dengan satu tampilan dan WHEREklausa.

Rachel
sumber
1
mengapa Anda bahkan menggunakan tampilan jika Anda hanya memiliki satu tabel di dalamnya?
HLGEM
3
Keamanan @HLGEM?
JNK
2
@HLGEM View sebenarnya berisi beberapa query ke beberapa database pada server yang berbeda, dan menggabungkan semuanya dengan a UNION ALL. Jauh lebih mudah menggunakan Tampilan daripada harus menulis ulang kueri UNION kapan pun saya membutuhkan data.
Rachel
1
@dagagod Saya akan mengingatnya, terima kasih :) Dalam hal ini, ada aplikasi yang cukup kecil yang mengumpulkan data dari sekelompok server, menjalankan beberapa perhitungan, dan mengeluarkan banyak laporan. Ini memiliki database sendiri karena beberapa perhitungannya cukup intensif sumber daya, dan saya ingin memisahkannya dari yang lain.
Rachel

Jawaban:

12

Anda seharusnya benar-benar tidak melihat perbedaan dalam rencana atau kinerja antara dua pilihan ini. Ketika tampilan ditanya, itu diperluas ke permintaan terhadap tabel dasar, yang berarti pencarian atau pemindaian yang sama akan digunakan.

Sekarang, tergantung pada tipe data dan selektivitas MyColumn, jika Anda ingin membuat indeks yang difilter pada tabel dasar (ketika Anda pindah ke SQL Server 2008+), Anda mungkin mendapatkan kinerja yang lebih baik, tetapi ini lagi tidak akan berbeda melalui tampilan atau tanpa.

Aaron Bertrand
sumber
3
Bagaimana dengan pertanyaan ini , yang menanyakan mengapa kueri dengan whereklausa di luar tampilan membutuhkan waktu lebih lama daripada saat dimasukkan dalam tampilan?
Rachel
1
Jika pandangan bukan untuk kinerja, itu hanya untuk struktur?
profimedica
1
@profimedica viewsed diindeks dapat dibuat untuk alasan kinerja (misalnya untuk menyimpan hasil perantara seperti agregat alih-alih menghitungnya saat runtime). Jika tampilan tidak terwujud, bisa karena berbagai alasan: KERING (penyatuan umum atau filter yang dilakukan dalam berbagai pertanyaan), keamanan, kebingungan, penyederhanaan skema.
Aaron Bertrand
5

Berikut ini hanya contoh singkat yang menunjukkan bahwa seharusnya tidak ada perbedaan. Basis data adalah AdventureWorksbasis data.

Definisi Dua Tampilan:

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

Ini akan menjadi permintaan pertama, dengan WHEREklausa yang disertakan dalam definisi tampilan:

select *
from person.vContactWhere

Berikut adalah rencana pelaksanaannya:

masukkan deskripsi gambar di sini

Dan permintaan kedua, dengan WHEREklausa tidak dalam definisi tampilan, tetapi dalam SELECTpermintaan:

select *
from person.vContactNoWhere
where ContactID = 24

Ini adalah rencana eksekusi:

masukkan deskripsi gambar di sini

Seperti yang Anda lihat dari rencana eksekusi ini, mereka identik dengan hasil yang identik. Saya tidak tahu situasi di mana jenis logika / desain ini akan menghasilkan hasil yang berbeda. Jadi saya bersedia mengatakan bahwa Anda aman, dan pergi dengan preferensi pribadi (atau prosedur berbelanja).

Thomas Stringer
sumber
1
Bagaimana dengan pertanyaan ini , yang menanyakan mengapa kueri dengan whereklausa di luar tampilan membutuhkan waktu lebih lama daripada saat dimasukkan dalam tampilan?
Rachel
1
@Rachel Saya pikir gbn menjelaskannya dengan baik di posnya, dan artikel yang dia tunjukkan. Saya tidak tahu bagaimana lagi mengatakannya.
Thomas Stringer
Saya mengaitkannya karena dalam kasus itu, rencana eksekusi tidak sama, yang berbeda dari apa yang Anda katakan.
Rachel
1
@Rachel Masalah dalam contoh itu adalah aturan transformasi yang hilang . Ini tidak hanya berlaku untuk tampilan tetapi juga CTE dan ekspresi tabel lainnya. Dalam kasus umum itu tidak sah untuk mendorong predikat ke ekspresi tabel yang berisi fungsi peringkat karena akan mengubah hasilnya. Alasan itu valid dalam kasus ini adalah karena Whereklausa cocok dengan PARTITION BY. SQL Server 2008 tampaknya memiliki aturan baru SelOnSeqPrjuntuk mengenali kasus khusus ini.
Martin Smith
2

Berdasarkan apa yang saya baca , SQL akan menggunakan tampilan standar seperti sub kueri saat menentukan rencana eksekusi.

Jadi, menggunakan contoh permintaan saya,

SELECT Id
FROM MyView
WHERE SomeColumn = 1

dimana MyViewdidefinisikan sebagai

SELECT Id, SomeColumn
FROM MyTable

harus menghasilkan rencana eksekusi yang sama dengan

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

tetapi rencana eksekusi ini mungkin berbeda dari apa yang akan dihasilkan

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

Saya tidak yakin apakah jawaban ini akan sama untuk Tampilan Berindeks

Rachel
sumber
Saya tidak berpikir itu pengganti teks eksplisit seperti itu.
Aaron Bertrand
@ AaronBertrand Anda mungkin benar. Jujur saya tidak tahu ... Saya belajar sambil jalan :) Asumsi itu didasarkan pada hal-hal lain yang saya baca tentang bagaimana pandangan seperti makro. Saya sedikit mengedit pertanyaan untuk menentukan bahwa saya mengacu pada tampilan standar, bukan tampilan yang diindeks.
Rachel
@ Rachel - Substitusi terjadi dengan pohon aljabar tidak pada tingkat tekstual.
Martin Smith
@ MartinSmith Hrrmm bukankah itu yang saya katakan? Bahwa rencana pelaksanaannya harus sama, bukankah teksnya akan sama? Saya tidak yakin bahwa saya memahami "pohon aljabar"
Rachel
Itu hanya sebagai tanggapan atas komentar Anda pada Q itu sendiri yang mengatakan bahwa itu "memasukkan teks Lihat ke dalam permintaan Anda" dan komentar Aaron di atas. Beberapa info tentang tahapan parsing / kompilasi di sini . Sebenarnya jawaban Anda juga menyebutkan subtitusi teks. Apakah ini merupakan perbedaan yang layak dibuat. Tidak yakin! Tapi saya kira itu menjelaskan mengapa sp_refreshviewdiperlukan konsep substitusi teks yang tidak.
Martin Smith