Saya menguji arsitektur yang berbeda untuk tabel besar dan satu saran yang saya lihat adalah menggunakan tampilan dipartisi, di mana tabel besar dipecah menjadi serangkaian lebih kecil, tabel "dipartisi".
Dalam menguji pendekatan ini, saya telah menemukan sesuatu yang tidak masuk akal bagi saya. Ketika saya memfilter pada "kolom partisi" pada tampilan fakta, pengoptimal hanya mencari di tabel yang relevan. Selain itu, jika saya memfilter pada kolom itu di tabel dimensi, pengoptimal menghilangkan tabel yang tidak perlu.
Namun, jika saya memfilter pada beberapa aspek lain dari dimensi pengoptimal mencari PK / CI dari setiap tabel dasar.
Inilah pertanyaan yang dimaksud:
select
od.[Year],
AvgValue = avg(ObservationValue)
from dbo.v_Observation o
join dbo.ObservationDates od
on o.ObservationDateKey = od.DateKey
where o.ObservationDateKey >= 20000101
and o.ObservationDateKey <= 20051231
group by od.[Year];
select
od.[Year],
AvgValue = avg(ObservationValue)
from dbo.v_Observation o
join dbo.ObservationDates od
on o.ObservationDateKey = od.DateKey
where od.DateKey >= 20000101
and od.DateKey <= 20051231
group by od.[Year];
select
od.[Year],
AvgValue = avg(ObservationValue)
from dbo.v_Observation o
join dbo.ObservationDates od
on o.ObservationDateKey = od.DateKey
where od.[Year] >= 2000 and od.[Year] < 2006
group by od.[Year];
Berikut tautan ke sesi SQL Sentry Plan Explorer.
Saya sedang mengerjakan benar-benar mempartisi tabel yang lebih besar untuk melihat apakah saya mendapatkan penghapusan partisi untuk merespons dengan cara yang sama.
Saya mendapatkan penghapusan partisi untuk kueri (sederhana) yang memfilter pada aspek dimensi.
Sementara itu, inilah salinan database yang hanya statistik:
https://gist.github.com/swasheck/9a22bf8a580995d3b2aa
Penaksir kardinalitas "lama" mendapatkan rencana yang lebih murah, tetapi itu karena perkiraan kardinalitas yang lebih rendah pada setiap indeks yang dicari (tidak perlu).
Saya ingin tahu apakah ada cara untuk mendapatkan pengoptimal menggunakan kolom kunci saat memfilter dengan aspek lain dari dimensi sehingga dapat menghilangkan mencari di tabel yang tidak relevan.
Versi SQL Server:
Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
Feb 20 2014 20:04:26
Copyright (c) Microsoft Corporation
Developer Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
sumber
CREATE STATISTICS [_WA_Sys_00000008_2FCF1A8A] ON [dbo].[Observation_2010]([StationStateCode]) WITH STATS_STREAM = 0x01000000010000000000000000000000D4531EDB00000000D5080000000000009508000000000000AF030000AF000000020000000000000008D000340000000007000000E65DE0007DA5000076F9780000000000867704000000000000000000ABAAAA3C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ObservationDates
tabel. Saya tidak mendapatkan rencana yang sama dengan Paul, bahkan dengan 4199, dan saya pikir inilah sebabnya.ObservationDates
. Saya akhirnya berjalanUPDATE STATISTICS ObservationDates WITH ROWCOUNT = 10000
secara manual untuk mendapatkan rencana yang ditunjukkan Paul.ObservationDates
jadi saya tidak yakin apa yang terjadi dengan itu. juga, saya tidak bisa mendapatkan rencana paul dihasilkan juga. Saya akan mencoba pembaruan untuk melihat.Jawaban:
Aktifkan tanda jejak 4199.
Saya juga harus mengeluarkan:
untuk mendapatkan rencana yang ditunjukkan di bawah ini. Statistik untuk tabel ini tidak ada dari unggahan. Angka 73.049 berasal dari informasi Kardinalitas Tabel di lampiran Plan Explorer. Saya menggunakan SQL Server 2014 SP1 CU4 (build 12.0.4436) dengan dua prosesor logis, memori maksimum diatur ke 2048 MB, dan tidak ada jejak jejak selain 4199.
Anda kemudian harus mendapatkan rencana eksekusi yang menampilkan penghapusan partisi dinamis:
Paket fragmen:
Ini mungkin terlihat lebih buruk, tetapi Filter adalah semua filter start-up . Contoh predikat adalah:
Per iterasi dari loop, predikat start-up diuji, dan hanya jika itu mengembalikan true adalah Indeks Clustered Carilah di bawahnya dieksekusi. Oleh karena itu, penghapusan partisi dinamis.
Hal ini mungkin tidak cukup seefisien penghapusan statis, terutama jika rencana tersebut sejajar.
Anda mungkin perlu mencoba petunjuk seperti
MAXDOP 1
,FAST 1
atauFORCESEEK
pada tampilan untuk mendapatkan paket yang sama. Pilihan penetapan biaya pengoptimal dengan tampilan yang dipartisi (seperti tabel yang dipartisi) bisa rumit.Intinya adalah Anda memerlukan rencana yang menampilkan filter start-up untuk mendapatkan penghapusan partisi dinamis dengan tampilan yang dipartisi.
Pertanyaan dengan
USE PLAN
petunjuk yang tersemat : (via gist.github.com):sumber
Pengamatan saya selalu bahwa Anda harus menentukan nilai (atau rentang nilai) untuk kolom partisi secara eksplisit dalam kueri untuk mendapatkan "penghapusan tabel" dalam tampilan yang dipartisi. Ini didasarkan pada pengalaman menggunakan tampilan dipartisi dalam produksi dari SQL Server 2000 hingga SQL Server 2014.
SQL Server tidak memiliki konsep loop join operator di mana mesin dapat secara dinamis mengarahkan pencarian langsung ke tabel yang tepat di sisi dalam loop berdasarkan nilai baris di sisi luar loop. Namun, seperti jawaban Paul menjelaskan , ada kemungkinan rencana dengan filter start-up untuk secara dinamis melewati tabel yang tidak relevan di sisi dalam loop dalam waktu yang konstan (sebagai lawan logaritmik dengan benar-benar melakukan pencarian).
Perhatikan bahwa untuk tabel yang dipartisi, jenis pencarian ini (ke partisi tertentu) didukung.
Jika Anda tetap menggunakan tampilan yang dipartisi, opsi lain adalah untuk membagi kueri Anda menjadi beberapa kueri, seperti:
Ini menghasilkan rencana berikut. Sekarang ada kueri tambahan yang mengenai tabel dimensi, tetapi kueri di atas tabel fakta (mungkin jauh lebih besar) dioptimalkan.
sumber
20000101
dan20051231
alih-alih variabel (atau lakukan sesuatu yang serupa melalui dua kueri terpisah di aplikasi Anda), maka ya, efek yang sama akan dicapai tanpa menggunakan variabel.