Sp_executesql sorgu planını ne zaman yeniler?


13

DBA olmadığım için naifliğimi affetmeniz gerekecek, ancak anlayışım, zaman içinde bir veritabanı değişikliğinin istatistiklerinin ve saklı bir yordamın en son istatistiklerle güncel tutulması için yeniden derlenmesi gerektiğidir.

Ben de son istatistikler karşı derlenmiş çekirdekler benim veritabanında saklı bir prosedür var varsayarsak bazı kod saklanan yordam in-astar ve bir sararak etkileri nelerdir, düzenli aralıklarla sp_executesqlaçıklamada? Yordamın yeniden derlenmesinin bir parçası olarak gerçekleşen sorgu planının yenilenmesini kaybediyor muyum?

Bu değişikliği yapmadan önce dikkate almam gereken başka bir şey varsa (izinler dışında), görüşlerinizi takdir ediyorum.

Bunu MSDN'de okudum:

SQL Server sorgu iyileştiricisinin yeni bir Transact-SQL dizesini varolan bir yürütme planıyla eşleştirme yeteneği, özellikle karmaşık Transact-SQL deyimlerinde dizenin metnindeki sürekli değişen parametre değerleri tarafından engellenir.

Satır içi ve sarmaya çalıştığım saklı yordamın sp_executesqlgerçekten bazı parametreler içerdiğini varsayarak, yürütme planım önbelleğe alınmış olmasına rağmen SQL Server'ın bulmasını ve yeniden kullanmasını zorlaştırıyor muyum?

Yanıtlar:


7

MSDN'den gelen satır şu şekilde kullanımdan bahsediyor EXEC():

SET @sql = 'SELECT foo FROM dbo.bar WHERE x = ''' + @x + ''';';
EXEC(@sql);

Testlerimde, SQL Server'ın modern sürümleri hala böyle bir planı yeniden kullanabilir, ancak başka değişkenler de olabilir (sürüm gibi veya örneğin WHEREbelirli parametrelerin varlığına dayalı koşullu hükümler eklerseniz - bu durumda farklı bir plan oluşturacak).

Eğer kullanırsanız sp_executesqlo zaman parametre değerleri hala (sadece normal SQL ile benzeri) sorunları koklama parametre neden olabilir, ancak bu SQL Server planını yeniden kullanıp kullanamayacağını ile ilgisi yoktur. Bu plan, sp_executesqldoğrudan sorguya neden olacak değişkenlerin yeniden derlenmesine izin verilmedikçe, hiç kullanmamışsınız gibi tekrar tekrar kullanılacaktır , bu durumda bu da yeniden derlenecektir (esas olarak, SQL Server "Bu, sp_executesql'den yürütüldü, ancak bu değildi) planıyla ilgili her şeyi depola:

SET @sql = N'SELECT foo FROM dbo.bar WHERE x = @x;';
EXEC sp_executesql @sql, N'@x VARCHAR(32)', @x;

Bonus olarak, bu dinamik SQL'e karşı yerleşik bir korumaya sahiptir ve dize sınırlayıcıları nedeniyle tek tırnakları ikiye katlama konusunda endişelenmenizi önler. Burada bunun hakkında blog yazdım .

Eğer planı yeniden kullanım ve / veya parametre koklama ile ilgili sorunlar yaşıyorsanız, size içine bakmak gereken bazı şeyler var OPTION (RECOMPILE), OPTIMIZE FOR, optimize for ad hoc workloadsve simple/forced parameterization. Burada son zamanlarda yayınlanan bir web yayınına yanıt olarak birkaç benzer soruya değindim, bir kaymaya değer olabilir:

http://sqlperformance.com/performance-palooza

Amaç: kullanmaktan korkmayın sp_executesql, ancak yalnızca ihtiyacınız olduğunda kullanın ve yalnızca gerçek bir performans sorununuz olduğunda aşırı optimizasyon için enerji harcayın. Yukarıdaki örnek korkunç bir örnek çünkü burada dinamik SQL kullanmak için bir neden yok - bu cevabı meşru bir kullanım vakanız olduğu varsayılarak yazdım.


2

Sp_executesql üzerinden çalıştırılan sorgular, normal sorgularla aynı yürütme planları kurallarını izler ve sp_executesql ile çalıştırılmaz. Sorgu metni değişirse, yeni bir plan oluşturulur. Parametrelerin kullanıcısı nedeniyle metin değişmezse, plan yeniden kullanılır. İstatistikler güncellendiğinde, planların süresi dolar ve sorgunun bir sonraki çalıştırılışında yeni planlar oluşturulur.


Cevabınız için teşekkürler, şimdi sp_ExecuteSql'i her aradığımda, Sql Server perspektifinden, değiştirdiğim için sorgu olarak farklı bir dize kullanacağımı fark ettiğim gibi parametrelerle ilgili bir düzenleme yaptım. sabit kodlanmış değerlere sahip parametreler (sorgumu Sql Server'a göndermeden önce kodda girilecekler). Bunun bir yolunu biliyor musun? Satır içi sql ifademdeki değişkenleri bildirmek, sorgu optimize edicisinin önbelleğe alınmış sorgu planımı bulmasına yardımcı olur mu?
james lewis
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.