Ek: SQL Server 2012, bu alanda bazı gelişmiş performans gösterir ancak aşağıda belirtilen belirli sorunların üstesinden gelmiyor gibi görünmektedir. Bu gerektiğini görünüşte sabit bir sonraki büyük versiyonu sonra
SQL Server 2012!
Planınız, tekli girişlerin parametreleştirilmiş prosedürleri (muhtemelen otomatik parametreleştirilmiş) kullandığını gösterir, bu nedenle bunlar için ayrıştırma / derleme süresi minimum olmalıdır.
Buna biraz daha bakacağımı düşündüm, bu yüzden bir döngü ( komut dosyası ) kurup VALUES
cümle sayısını ayarlamayı ve derleme süresini kaydetmeyi denedim .
Daha sonra cümle başına ortalama derleme süresini elde etmek için derleme süresini satır sayısına böldüm. Sonuçlar aşağıda
250 VALUES
cümle sunulana kadar , derleme süresi / cümle sayısı hafif bir yükseliş eğilimi gösterir, ancak çok dramatik bir şey yoktur.
Ama sonra ani bir değişiklik olur.
Verilerin bu bölümü aşağıda gösterilmiştir.
+------+----------------+-------------+---------------+---------------+
| Rows | CachedPlanSize | CompileTime | CompileMemory | Duration/Rows |
+------+----------------+-------------+---------------+---------------+
| 245 | 528 | 41 | 2400 | 0.167346939 |
| 246 | 528 | 40 | 2416 | 0.162601626 |
| 247 | 528 | 38 | 2416 | 0.153846154 |
| 248 | 528 | 39 | 2432 | 0.157258065 |
| 249 | 528 | 39 | 2432 | 0.156626506 |
| 250 | 528 | 40 | 2448 | 0.16 |
| 251 | 400 | 273 | 3488 | 1.087649402 |
| 252 | 400 | 274 | 3496 | 1.087301587 |
| 253 | 400 | 282 | 3520 | 1.114624506 |
| 254 | 408 | 279 | 3544 | 1.098425197 |
| 255 | 408 | 290 | 3552 | 1.137254902 |
+------+----------------+-------------+---------------+---------------+
Doğrusal olarak büyüyen önbelleğe alınmış plan boyutu aniden düşer, ancak CompileTime 7 kat artar ve CompileMemory yükselir. Bu, planın otomatik olarak parametrik hale getirilmiş (1.000 parametreli) ile parametrik olmayan bir plan arasında kesilme noktasıdır. Bundan sonra (belirli bir zamanda işlenen değer cümlelerinin sayısı bakımından) doğrusal olarak daha az verimli hale geliyor gibi görünüyor.
Bunun neden olması gerektiğinden emin değilim. Muhtemelen belirli değişmez değerler için bir plan derlerken, doğrusal olarak ölçeklenmeyen (sıralama gibi) bazı etkinlikler gerçekleştirmesi gerekir.
Tamamen yinelenen satırlardan oluşan bir sorguyu denediğimde önbelleğe alınan sorgu planının boyutunu etkilemiyor gibi görünüyor ve sabitlerin tablosunun çıktısının sırasını etkilemiyor öyle olsa bile anlamsız olurdu).
Dahası, tabloya kümelenmiş bir dizin eklenirse, plan yine de açık bir sıralama adımı gösterir, bu nedenle çalışma zamanında bir sıralamayı önlemek için derleme zamanında sıralanıyor gibi görünmez.
Buna bir hata ayıklayıcıda bakmaya çalıştım, ancak SQL Server 2008 sürümüm için genel semboller mevcut görünmüyor, bu yüzden bunun yerine UNION ALL
SQL Server 2005'teki eşdeğer yapıya bakmak zorunda kaldım .
Tipik bir yığın izi aşağıdadır
sqlservr.exe!FastDBCSToUnicode() + 0xac bytes
sqlservr.exe!nls_sqlhilo() + 0x35 bytes
sqlservr.exe!CXVariant::CmpCompareStr() + 0x2b bytes
sqlservr.exe!CXVariantPerformCompare<167,167>::Compare() + 0x18 bytes
sqlservr.exe!CXVariant::CmpCompare() + 0x11f67d bytes
sqlservr.exe!CConstraintItvl::PcnstrItvlUnion() + 0xe2 bytes
sqlservr.exe!CConstraintProp::PcnstrUnion() + 0x35e bytes
sqlservr.exe!CLogOp_BaseSetOp::PcnstrDerive() + 0x11a bytes
sqlservr.exe!CLogOpArg::PcnstrDeriveHandler() + 0x18f bytes
sqlservr.exe!CLogOpArg::DeriveGroupProperties() + 0xa9 bytes
sqlservr.exe!COpArg::DeriveNormalizedGroupProperties() + 0x40 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x18a bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!CQuery::PqoBuild() + 0x3cb bytes
sqlservr.exe!CStmtQuery::InitQuery() + 0x167 bytes
sqlservr.exe!CStmtDML::InitNormal() + 0xf0 bytes
sqlservr.exe!CStmtDML::Init() + 0x1b bytes
sqlservr.exe!CCompPlan::FCompileStep() + 0x176 bytes
sqlservr.exe!CSQLSource::FCompile() + 0x741 bytes
sqlservr.exe!CSQLSource::FCompWrapper() + 0x922be bytes
sqlservr.exe!CSQLSource::Transform() + 0x120431 bytes
sqlservr.exe!CSQLSource::Compile() + 0x2ff bytes
Yani yığın izlemesindeki isimleri gözden kaçırmak, dizeleri karşılaştırmak için çok zaman harcıyor gibi görünüyor.
Bu KB makalesi , sorgu işlemenin normalleştirme aşaması DeriveNormalizedGroupProperties
olarak adlandırılan şeyle ilişkili olduğunu gösterir.
Bu aşama artık bağlama veya cebirleme olarak adlandırılır ve ifade ayrıştırma ağacı çıktısını önceki ayrıştırma aşamasından alır ve optimizasyona (bu durumda önemsiz plan optimizasyonu) ilerlemek için cebirlendirilmiş bir ifade ağacı (sorgu işlemci ağacı) çıkarır [ref] .
Orijinal testi yeniden çalıştıracak, ancak üç farklı duruma bakacak bir deney daha ( Script ) denedim .
- 10 karakter uzunluğunda ve yinelenmemiş Ad ve Soyad Dizeleri.
- 50 karakter uzunluğunda, yinelenmemiş Ad ve Soyad Dizeleri.
- Tüm kopyaları olan 10 karakter uzunluğunda Ad ve Soyadı Dizeleri.
Açıkça görülebilir ki, dizeler ne kadar uzun olursa, daha kötü şeyler olur ve tersine, ne kadar çok kopya olursa, o kadar iyi olur. Daha önce bahsedildiği gibi, kopyalar önbelleğe alınmış plan boyutunu etkilemez, bu yüzden cebri ifade ağacının kendisini oluştururken bir yinelenen tanımlama süreci olması gerektiğini varsayıyorum.
Düzenle
Bu bilgilerin kullanıldığı bir yer @Lieven tarafından burada gösterilmektedir
SELECT *
FROM (VALUES ('Lieven1', 1),
('Lieven2', 2),
('Lieven3', 3))Test (name, ID)
ORDER BY name, 1/ (ID - ID)
Derleme zamanında, Name
sütunun yinelemeleri olmadığını belirleyebildiğinden 1/ (ID - ID)
, çalışma zamanında ikincil ifadeye göre sıralamayı atlar (plandaki sıralamada yalnızca bir ORDER BY
sütun vardır) ve sıfıra bölme hatası oluşmaz. Tabloya kopyalar eklenirse, sıralama operatörü sütunlara göre iki sıra gösterir ve beklenen hata ortaya çıkar.