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

Mengapa Pengoptimal Kueri sama sekali mengabaikan indeks tampilan yang diindeks?

tl;dr answer:Jika Anda tidak menentukan NOEXPAND, pengoptimal kueri tidak tahu bahwa Anda mengirimkan pilihan sederhana dari tampilan. Itu harus cocok dengan perluasan kueri Anda (hanya itu yang dilihatnya) dengan beberapa indeks tampilan. Mungkin tidak akan mengganggu jika itu adalah gabungan lima arah dengan sekelompok pemain.

Pencocokan indeks tampilan dengan kueri adalah masalah yang sulit, dan saya yakin tampilan Anda terlalu rumit untuk mesin kueri untuk dicocokkan dengan indeks. Pertimbangkan ini salah satu pertanyaan Anda:

SELECT ID, Code1 FROM EntityView Where Code1 > 'NR%';

Jelas bagi Anda bahwa ini dapat menggunakan indeks tampilan, tetapi ini bukan kueri yang dilihat oleh mesin kueri. Tampilan diperluas secara otomatis jika Anda tidak menentukan NOEXPAND, jadi inilah yang masuk ke mesin kueri:

SELECT ID, Code1 FROM (
    SELECT e.ID, 'NR'+CAST(c1.CODE as nvarchar(11)) as Code1, 'NR'+CAST(c2.CODE as nvarchar(11)) as Code2, 'NR'+CAST(c3.CODE as nvarchar(11)) as Code3, 'NR'+CAST(c4.CODE as nvarchar(11)) as Code4, 'NR'+CAST(c5.CODE as nvarchar(11)) as Code5
    FROM dbo.Entity e
        inner join  dbo.Classificator1 c1 on e.ID = c1.ID
        inner join  dbo.Classificator2 c2 on e.ID = c2.ID
        inner join  dbo.Classificator3 c3 on e.ID = c3.ID
        inner join  dbo.Classificator4 c4 on e.ID = c4.ID
        inner join  dbo.Classificator5 c5 on e.ID = c5.ID;
) AS V;

Mesin kueri melihat kueri rumit ini, dan memiliki informasi (tetapi mungkin bukan SQL definisi tampilan) yang menjelaskan indeks tampilan yang telah ditentukan. Mengingat bahwa kueri ini dan indeks tampilan keduanya memiliki banyak gabungan dan pemeran, pencocokan adalah pekerjaan yang sulit.

Ingatlah bahwa Anda tahu bahwa gabungan dan kecocokan identik dalam kueri ini dan indeks tampilan, tetapi pemroses kueri tidak mengetahuinya. Ini memperlakukan kueri ini sama seperti jika ia menggabungkan lima salinan Classificator3, atau jika salah satu kolomnya adalah 'NQ'+CAST(c2.CODE sebagai varchar(12)). Pencocokan indeks tampilan (dengan asumsi ia melakukan segala upaya untuk mencocokkan kueri yang rumit ini) harus mencocokkan setiap detail kueri ini dengan detail indeks tampilan pada tabel yang terlibat.

Mesin kueri memiliki tujuan #1 untuk mencari cara untuk mengeksekusi kueri secara efisien. Ini mungkin tidak dirancang untuk menghabiskan banyak waktu mencoba mencocokkan setiap detail dari gabungan lima arah dan CAST ke indeks tampilan.

Jika saya harus menebak, saya menduga pencocok indeks tampilan melihat bahwa kolom hasil kueri bahkan bukan kolom dari tabel yang mendasarinya (karena CAST) dan tidak repot-repot mencoba apa pun. Ditambahkan :Aku salah. Saya baru saja mencoba saran Martin untuk memperbarui statistik untuk membuat kueri mahal, dan indeks tampilan cocok untuk beberapa kueri ini tanpa NOEXPAND. Pencocokan tampilan lebih pintar dari yang saya kira! Jadi masalahnya adalah view matcher mungkin berusaha lebih keras untuk mencocokkan kueri yang rumit jika biayanya sangat tinggi.

Gunakan petunjuk NOEXPAND alih-alih mengharapkan mesin kueri dapat mengetahui apa yang cocok di sini. NOEXPAND benar-benar teman Anda, karena mesin kueri dapat melihat

SELECT ID, Code1 FROM EntityView Where Code1 > 'NR%';

dan kemudian segera jelas bagi pencocok indeks tampilan bahwa ada indeks yang berguna.

(Catatan:Kode SQL Fiddle Anda memiliki 5 referensi kunci asing ke tabel yang sama, yang mungkin bukan yang Anda inginkan.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apa itu OLAP CUBE Multi Dimensi dan berikan contoh kubus lebih dari 3 dimensi

  2. Membaca file teks dengan SQL Server

  3. Menggunakan .Include() saat menggabungkan tampilan menggunakan Entity Framework

  4. Cara Mendapatkan Definisi Kolom Terhitung di SQL Server menggunakan T-SQL

  5. Variabel server SQL:loop vs duplikat?