2016-04-01 14 views
1

LAG kullanan bir görünüm var.Pencere işlevleri görünümünde "nerede" kötü yürütme planı veriyor

CREATE VIEW V_ImportedReadingDay2 
AS 
SELECT 
    ID, 
    PlacementID, 
    LAG(Reading, 1) OVER (PARTITION BY MeterNumber ORDER BY Date) AS Val 
FROM dbo.ImportedReadingDay 

kullanıyorum diyoruz "Eğer NEREDE" sadece sorguyu çağırarak eğer daha kötü bir yürütme planı olur.

SELECT 
    ID, 
    PlacementID, 
    LAG(Reading, 1) OVER (PARTITION BY MeterNumber ORDER BY Date) AS Val 
FROM dbo.ImportedReadingDay 
WHERE (PlacementID = 12404) 

SELECT * 
FROM V_ImportedReadingDay2 
WHERE (PlacementID = 12404) 

enter image description here

Bu bilinen bir sorundur. Sorunu google yapabilirsiniz. İki çözüm buldum. Tablo değerli bir işlev kullanın veya LAG'yi görünümün dışına taşıyın.

ANCAK BUNLARIN KULLANIM KILAVUZU OLUŞTURMAK İÇİN BUNLARDAN BAŞVURABİLİRSİNİZ.

cevap

3

İki sorgunuz mantıksal olarak aynı değil. Yani, elbette, aynı yürütme planını almıyorlar.

bu sorguları göz önünde bulundurun:

select name,LAG(column_id) OVER (ORDER BY system_type_id) as cid 
from sys.columns 
where name='name' 

select * from (
select name,LAG(column_id) OVER (ORDER BY system_type_id) as cid 
from sys.columns 
) t 
where name='name' 

için sorgular mantıksal işlem düzeninin, WHERE maddesi SELECT madde önce işlenir. Yani, ilk sorgu için, ilk ilk tablosunu sadece belirli bir isimle satırları almak içintablosunu filtreleyin ve sonra biz sadece bu filtrelenmiş sette LAG() işlevini uygulayın (böylece gecikmeli değer başka bir satırdan gelecektir) filtreyle eşleşen).

İkinci sorgu için alt sorgusu önce (mantıksal olarak) işliyoruz. Tüm satırlar boyunca LAG() işlevini gerçekleştiriyoruz (alt sorguda herhangi bir filtre bulunmadığından/WHERE yan tümcesi) ve sonra (dış sorguda) satır kümesini filtreleriz. Önemli olarak, bu, gecikmeli değerin, son filtreyle uyuşmayan bir satırdan çekilmiş olabileceği anlamına gelir.

Bir görünüm kullandığınızda, ikinci sorguya benzer. Görünümünüzü kullandığınızda alınan Val değeri , PlacementID12404'a eşit bir satırdan olma garantisidir.

+0

Bildiğim kadarıyla basitleştirilmişlerdir. – Kvasi

+0

Aynı analiz hala geçerli - tablo davası karşısında doğrudan sorgulamada, mantıksal olarak * filter * ve * sonra * 'LAG', ve view sorgusunda, filtreden önce LAG'sindesiniz. Onlar hala mantıklı, farklı sorgular. –

+0

Evet, LAG, aynı filtreyle eşleşmeyen bir satırdan alınabilmesi gerekiyordu; çünkü değer, Okuma değerini sıfırlamadan bir yerleşmeden diğerine taşınmış olabilecek bir metreye ait. Yine de, bir LAG değerinin bir önceki yerleşime doğru bir şekilde ait olabilse bile yararlı olmadığını fark ettim. Evet, aynı olmadıklarına dair doğrusınız. – Kvasi

1

Bu, bu örnek için basitleştirilmiş bir görünümdü. Gerçek olana LAG'yi bölüyorum. LAG'ın "WHERE" (bu durumda PlacementID) 'de kullanılanla aynı bölümle ayrıştırılmasının performans sorununu çözdüğünü öğrendim.