Operatör, dökülme seviyesi 2 ile yürütme sırasında verileri dökmek için tempdb'yi kullandı


18

Uyarı Operator usedtempdb ile bir sorgu planı sıralama işlemi maliyetini en aza indirmek için mücadele ediyorumto spill data during execution with spill level 2

Birkaç ilgili yayınları bulduk dökmek seviye 1 ile yürütülürken dökmek verilerine 2. seviye değil, Seviye 1 kaynaklandığı met modası geçmiş istatistiklerini görünüyor , hangi seviyede yaklaşık 2? İle ilgili hiçbir şey bulamadım level 2.

Bu makaleyi Sıralama uyarılarıyla ilgili çok ilginç buldum:

SQL Server'da bir sıralama uyarısını asla yoksay

SQL Server?

Microsoft SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64) 17 Haziran 2016 19:14:09 Telif Hakkı (c) Windows NT 6.3 üzerinde Microsoft Corporation Enterprise Edition (64 bit) (Derleme 9600:) (Hipervizör)

Donanımım?

harware'i bulmak için aşağıdaki sorguyu çalıştırmak:

- SQL Server 2012'den donanım bilgileri

SELECT cpu_count AS [Logical CPU Count], hyperthread_ratio AS [Hyperthread Ratio],
cpu_count/hyperthread_ratio AS [Physical CPU Count], 
physical_memory_kb/1024 AS [Physical Memory (MB)], affinity_type_desc, 
virtual_machine_type_desc, sqlserver_start_time
FROM sys.dm_os_sys_info WITH (NOLOCK) OPTION (RECOMPILE);

resim açıklamasını buraya girin

tahsis edilmiş bellek

SELECT
(physical_memory_in_use_kb/1024) AS Memory_usedby_Sqlserver_MB,
(locked_page_allocations_kb/1024) AS Locked_pages_used_Sqlserver_MB,
(total_virtual_address_space_kb/1024) AS Total_VAS_in_MB,
process_physical_memory_low,
process_virtual_memory_low
FROM sys.dm_os_process_memory;

resim açıklamasını buraya girin

sorgumu bir yıl kapsamı ile çalıştırdığımda aşağıdaki resme göre herhangi bir uyarı almıyorum:

resim açıklamasını buraya girin

Ama sadece 1 günlük kapsam için çalıştırdığımda bu uyarıyı alıyorum on the sort operator:

resim açıklamasını buraya girin

bu sorgu:

    DECLARE @FromDate SMALLDATETIME = '19-OCT-2016 11:00'
    DECLARE @ToDate   SMALLDATETIME = '20-OCT-2016 12:00'




    SELECT      DISTINCT
                a.strAccountCode ,
                a.strAddressLine6 ,
                a.strPostalCode ,
                CASE    WHEN a.strCountryCode IN ('91','92') THEN 'GB-Int'
                        ELSE a.strCountryCode
                        END AS [strCountryCode]
    FROM        Bocss2.dbo.tblBAccountParticipant AS ap
    INNER JOIN  Bocss2.dbo.tblBAccountParticipantAddress AS apa ON ap.lngParticipantID = apa.lngParticipantID
                                                                AND apa.sintAddressTypeID = 2
    INNER JOIN  Bocss2.dbo.tblBAccountHolder AS ah ON ap.lngParticipantID = ah.lngParticipantID
    INNER JOIN  Bocss2.dbo.tblBAddress AS a ON apa.lngAddressID = a.lngAddressID
                                            AND a.blnIsCurrent = 1
    INNER JOIN  Bocss2.dbo.tblBOrder AS o ON ap.lngParticipantID = o.lngAccountParticipantID
                                        AND o.sdtmOrdCreated >= @FromDate
                                        AND o.sdtmOrdCreated < @ToDate

OPTION(RECOMPILE)

sorgu planı burada

pasajı kullanarak sorgu planı

Sorular: 1) sorgu planında şunu görüyorum:

StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="70" 

neden 70? Sql server 2014 kullanıyorum

2) bu tür operatörden nasıl kurtulurum (mümkünse)?

3) Bu sunucuya daha fazla bellek ekleyerek sayfa ömrü beklentisini oldukça düşük gördüm, bu uyarıyı önleyip önleyemeyeceğimi görmek için bakabileceğim başka bir şey var mı?

şerefe

Shanky ve Paul White'ın cevabından sonra güncelleme

İstatistiklerimi aşağıdaki senaryoya göre kontrol ettim ve hepsi doğru ve güncel görünüyor.

bunların hepsi bu sorguda kullanılan dizinler ve tablolardır.

DBCC SHOW_STATISTICS ('dbo.tblBAddress','IDXF_tblBAddress_lngAddressID__INC')
GO
DBCC SHOW_STATISTICS  ('dbo.tblBOrder','IX_tblBOrder_sdtmOrdCreated_INCL')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountHolder','PK_tblAccountHolder')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountParticipant','PK_tblBAccountParticipants')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountParticipantAddress','IDXF_tblBAccountParticipantAddress_lngParticipantID')
GO

Ben geri döndü budur:

resim açıklamasını buraya girin

resim açıklamasını buraya girin

Bu kısmi bir sonuç, ama hepsini tekrar ziyaret ettim.

İstatistik güncellemesi için şu anda Ola Hallengren var

Haftada bir kez çalışması planlanan Endeks Optimizasyon İşi - Pazar günleri

EXECUTE [dbo].[IndexOptimize] 
@Databases = 'USER_DATABASES,-%Archive', 
@Indexes = 'ALL_INDEXES' , 
@FragmentationLow = NULL,
@FragmentationMedium = NULL,
@FragmentationHigh = NULL,
@PageCountLevel=1000,
@StatisticsSample =100
,@UpdateStatistics = 'Index', 
@OnlyModifiedStatistics = 'Y',
@TimeLimit=10800, 
@LogToTable = 'Y'

İstatistikler güncellenmiş gibi görünse de Aşağıdaki komut dosyasını çalıştırdıktan sonra, sıralama operatörü hakkında hiçbir uyarı almadım.

UPDATE STATISTICS [Bocss2].[dbo].[tblBOrder]  WITH FULLSCAN
--1 hour  04 min 14 sec

UPDATE STATISTICS [Bocss2].[dbo].tblBAddress  WITH FULLSCAN
-- 45 min 29 sec

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountHolder WITH FULLSCAN
-- 26 SEC

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountParticipant WITH FULLSCAN
-- 4 min

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountParticipantAddress WITH FULLSCAN
-- 7 min 3 sec

Sorgu süresi ne kadar azaldı?
nüfuz

İstatistikleri böylesine büyük masalarda güncel tutmamı sağlayacak bir çözüm asla uygulayamadım. Çözüm, tabloları bölümlemek ve artım istatistiklerini kullanmak olacaktır, ancak bunu uygulamak için hiç gelmedim çünkü o işverenden ayrıldım. Gerçi uygulamak istediğim bir şey.
Marcello Miorelli

Yanıtlar:


17

2. seviyeye ne dersin? Seviye 2 ile ilgili hiçbir şey bulamadım.

Gereğince bu eski MS Doc verileri sıralamak için veriler üzerinde gerekli kaç kez geçmesi Tempdb sızıntısı anlamına numara. Dolayısıyla Dökülme 1, verileri sıralamak için 1 kez ve 2 kez 2 kez geçmek zorunda olduğu anlamına gelir.

Blogdan alıntı:

Bir sıralama işlemi içeren bir sorgu, dökülme seviyesi değeri 2 olan bir Sıralama Uyarıları olay sınıfı oluşturursa, verileri sıralamak için verilerin üzerinde birden fazla geçiş yapılması gerektiğinden, sorgunun performansı etkilenebilir. Aşağıdaki örnekte dökülme seviyesi değeri 1 olarak görüldü, yani verilerin üzerinden bir geçişin sıralamayı tamamlamak için yeterli olduğu anlamına gelir.

neden 70? Sql server 2014 kullanıyorum

Bunun nedeni, resimdeki veritabanının uyumluluk düzeyinin 120 olmamasıdır (2014 veritabanının uyumluluk düzeyini gösterir), çünkü 120 sorgu olarak adlandırılan eski kardinalite tahmini (CE) modeli kullanılarak işlenecektir CardinalityEstimationModelVersion="70". Eminim ki SQL Server 2014'ten yeni CE'ye sahibiz.

bu tür operatörden nasıl kurtulurum (mümkünse)?

Kullandığınız farklı komut sıralama işlemine neden oluyor. Sıralanan veriler belleğe sığmaz, bu nedenle tempdb'ye dökülür ve bu olduğunda yürütme planında sarı ünlem işaretli bir sıralama uyarısı verilir. Sıralama uyarıları her zaman bir sorun oluşturmaz.

Yürütme planında, sıralanacak tahmini satır sayısının 1 olduğunu, ancak çalışma zamanında 16.353 ile karşılaşıldığını görebilirsiniz. Sıralama için ayrılan bellek miktarı , girdinin beklenen (tahmini) büyüklüğüne bağlıdır ve yürütme sırasında (bu durumda) büyüyemez.

Sorgu için küçük bellek desteği (1632KB), aynı anda yürütülen bellek tüketen işleçler arasında sıralanır (sıralama ve 'optimize edilmiş' döngü birleşimleri). Planınızda, bu, satırları okurken sıralamaya göre% 33,33 (544 KB) kullanılabilir olduğu anlamına gelir (giriş belleği bölümü). O kadar dökülen böylece bu, 16.353 satırları sıralamak için yeterli bellek değil tempdb . Sıralamayı tamamlamak için tek seviyeli bir dökülme yeterli değildir, bu nedenle ikinci bir dökülme seviyesi gereklidir (dökülme seviyeleri hakkında daha fazla ayrıntı için sondaki referansa bakın).

Özellikleri sırala

SQL Sentry Plan Explorer'da görüntülenen özellikleri sıralama

İstatistiklerin güncellenmesi büyük olasılıkla kardinalite tahmini sorununa yardımcı olacaktır. Özellikle masada, artan anahtar sorunu yaşıyor olabilirsiniz tblBOrder. Sorunuzdan gerçek tarihler içeren bu tablodan yapılan basit bir seçim, büyük olasılıkla şu anda bir satırı tahmin edecektir.

Bu sunucuya daha fazla bellek ekleyerek sayfa ömrü beklentisini oldukça düşük gördüm, bu uyarıyı önleyip önleyemeyeceğimi görmek için bakabileceğim başka bir şey var mı?

PLE, G / Ç etkinliğinin miktarının bir göstergesidir, arttı mı? Bu, sık sık mı yoksa yalnızca belirli bir sorguyu çalıştırdığınızda mı, yoksa yalnızca bugün gerçekleştiğinde mi gerçekleşir. Diz sarsıntısı reaksiyonundan kaçının, önce gerçekten bellek baskısıyla veya çok fazla G / Ç üreten bir haydut sorguyla karşı karşıya olduğunuzdan emin olmamız gerekir. Zaten SQL Server'a zaten 97 G belleğiniz var.

Dökülme seviyeleri ve artan anahtar sorunu hakkında daha fazla bilgi için, bkz:

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.