Birden çok değeri olan tek EKLE vs birden fazla INSERT deyimleri
1000 INSERT deyimleri kullanarak performans arasında bir karşılaştırma yapıyorum.
INSERT INTO T_TESTS (TestId, FirstName, LastName, Age)
VALUES ('6f3f7257-a3d8-4a78-b2e1-c9b767cfe1c1', 'First 0', 'Last 0', 0)
INSERT INTO T_TESTS (TestId, FirstName, LastName, Age)
VALUES ('32023304-2e55-4768-8e52-1ba589b82c8b', 'First 1', 'Last 1', 1)
...
INSERT INTO T_TESTS (TestId, FirstName, LastName, Age)
VALUES ('f34d95a7-90b1-4558-be10-6ceacd53e4c4', 'First 999', 'Last 999', 999)
..karşı 1000 değerleri ile tek INSERT deyimi kullanarak:
INSERT INTO T_TESTS (TestId, FirstName, LastName, Age)
VALUES
('db72b358-e9b5-4101-8d11-7d7ea3a0ae7d', 'First 0', 'Last 0', 0),
('6a4874ab-b6a3-4aa4-8ed4-a167ab21dd3d', 'First 1', 'Last 1', 1),
...
('9d7f2a58-7e57-4ed4-ba54-5e9e335fb56c', 'First 999', 'Last 999', 999)
Benim için büyük sürpriz oldu, sonuçları ne düşündüğümü tam tersi
- 1000 INSERT deyimleri:290 milisaniye.
- 1000 ile 1 INSERT deyimi DEĞERLERİ:2800 MSN.
Test yürütülen doğrudan MSSQL Management Studio ile SQL Server Profiler kullanılan ölçme (ve bende benzer sonuçları çalışan C# kodu kullanarak SqlClient, hangisi daha şaşırtıcı düşünürsek her DAL katmanları gidiş-dönüş)
Bu mantıklı ya da bir şekilde açıklanabilir? Gel, sözde daha hızlı bir yöntem 10 kat sonuçları nasıl (!)daha kötüperformans?
Teşekkür ederim.
EDİT: hem Ekleme yürütme planları:
CEVAP
Ayrıca:SQL Server 2012 bu alanda bazı gelişmiş performans gösterir ama belirli konular aşağıda belirtildiği mücadele etmiyor. Bu apparently be fixed bir sonraki sürümdesonra SQL Server 2012!
Planın tek ekler parametrik prosedürleri (muhtemelen otomatik parametrik) bu en az olması için derleme/ayrıştırma kullandığını gösterir.
Bu yüzden bir döngü kurmak olsa biraz daha fazla (script) içine bakmak istedim ve VALUES
fıkralar sayısı ayarlama ve derleme kaydı çalıştı.
Ben o satır sayısı ile derleme süresi ortalama tümce başına derleme için ayrılmıştır. Sonuçları aşağıda verilmiştir
VALUES
250 hükümleri günümüze kadar tümceleri derleme / sayısı hafif bir artış eğilimi ama etkileyici bir şey yoktu.
Ama sonra ani bir değişim var.
Verilerin 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 |
------ ---------------- ------------- --------------- ---------------
Büyümekte olan alınan plan boyutu doğrusal aniden düşer ama Derleme artar 7 kat ve CompileMemory vuruyor. Bu planın bir otomatik olarak bir sigara parametrize birebir (1,000 parametreleri ile) parametrize arasında kesti noktasıdır. Daha sonra doğrusal olarak daha az verimli (değer hükümleri belirli bir süre içinde işlenmiş sayısı bakımından) gibi görünüyor.
Bu neden emin değilim. Muhtemelen belirli değişmez değerler için bir plan derlerken doğrusal (sıralama) ölçek yapan bir aktivite yapmak gerekir.
Burası pek etkisi boyutu önbelleğe alınan sorgu planı çalıştım bir sorgu oluşan tamamen yinelenen satırları ve ne etkiler sipariş tablo çıktı sabitleri (ve eklediğiniz içine bir yığın zaman geçirdim sıralama olurdu zaten anlamsız bile yaptım).
Ayrıca eğer kümelenmiş bir dizin plan derleme zamanında sıralama için çalışma zamanında bir tür önlemek için görünmüyor yani hala açık sıralama bir adım gösterir tabloya eklenir.
Denedim bak bu bir hata ayıklayıcı ama ortak sembolleri için benim sürüm SQL Server 2008 yok gibi görünüyor mevcut bu yüzden onun yerine ben vardı bakmak için eşdeğer UNION ALL
Yapım SQL Server 2005.
Tipik bir izleme altına yığın
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
Bu kadar yığın içinde adlarını gidiyor çok fazla zaman harcamak dizeleri karşılaştırmak için görünür bir iz.
This KB article DeriveNormalizedGroupProperties
sorgu işleme normalization sahneye çağrılacak kullanılan ne ile ilişkili olduğunu gösterir
Bu aşama artık ismi bağlama veya algebrizing ve aldığı ifade ayrıştırma ağacı çıktı önceki ayrıştırma aşaması ve çıkışları bir algebrized ifade ağacı (sorgu işlemci ağacı) ileri gitmek için optimizasyon (önemsiz planı optimizasyonu bu durumda) [ref].
Yeniden çalıştırmak için orijinal test ama üç farklı durumda bakıyordu hangisi daha fazla deney (Script) çalıştım.
- Yineleme yok ile uzunluğu 10 karakter Adı ve soyadı Dizeleri.
- Yineleme yok ile uzunluğu 50 karakter Adı ve soyadı Dizeleri.
- Tüm çiftleri uzunluğu 10 karakter Adı ve soyadı Dizeleri.
Açıkça uzun dizeleri şeyler alıp tersine daha kötü çiftleri daha iyi şeyler görülebilir. Daha önce de belirttiğim gibi çiftleri algebrized ifade ağacın kendisi oluştururken yinelenen tanımlama süreci olması gerektiğini düşünüyorum bu yüzden alınan plan boyutunu etkilemiyor.
Edit
Bu bilgiler kaldıraçlı olduğu bir yer shown by @Lieven here
SELECT *
FROM (VALUES ('Lieven1', 1),
('Lieven2', 2),
('Lieven3', 3))Test (name, ID)
ORDER BY name, 1/ (ID - ID)
Çünkü derleme zamanında belirlemek Name
sütun var yineleme yok atlar sıralamaya göre ikincil 1/ (ID - ID)
ifadesi çalışma zamanında (sıralama planı yalnızca ORDER BY
sütun) ve sıfıra bölmek hatadır kaldırdı. Eğer yinelenen tabloya eklenirse o zaman sıralama işleç, iki sütun düzeni gösterir ve beklenen hata ortaya çıkar.
Daha hızlı olan: birden fazla tek Ekle...
Sürgün yolunda birden fazla parametre ...
mysql içine php bir dizi ile birden fa...
Vim içinde nasıl etkin bir şekilde bir...
Birden fazla değişkene aynı değeri ata...