Bu gönderi eksik bilgi nedeniyle tam bir cevap olmasa da, sizi doğru yöne yönlendirebilir veya daha sonra toplulukla paylaşabileceğiniz bir fikir edinebilmelidir.
Ne yazık ki, bu tanım disk tabanlı bir tablodaki önceki duruma göre performansın düşmesine neden olur. Büyüklük sırası% 10 daha fazla veya daha azdır (bazı durumlarda% 100'e ulaşır, bu nedenle iki kez).
En önemlisi, Microsoft'un reklamını yaptığı kilitsiz mimari göz önüne alındığında, yüksek eşzamanlılık senaryolarında süper bir avantaj elde etmeyi umuyordum. Bunun yerine, en kötü performanslar tam olarak masada birkaç sorgu çalıştıran birkaç eşzamanlı kullanıcı olduğunda gerçekleşir.
Kesinlikle durum böyle olmamalı çünkü bu rahatsız edici. Bellek tablolarında (SQL 2014) bazı iş yükleri için kullanılmaz ve bazı iş yükleri buna katkıda bulunur. Çoğu durumda, yalnızca uygun dizinleri geçirip seçerek performansta minimum bir artış olabilir.
Aslında bununla ilgili sorularınız hakkında çok dar düşünüyordum:
Sorular:
- ayarlanacak doğru BUCKET_COUNT nedir?
- ne tür bir dizin kullanmalıyım?
- performans neden disk tabanlı tablodan daha kötü?
Başlangıçta bellek tablosunda gerçek bir sorun olduğuna inandım ve indeksler optimal değildi. Bellek için optimize edilmiş karma indeks tanımı ile ilgili bazı sorunlar olsa da ben gerçek sorunun kullanılan sorguları ile olmak inanıyorum.
-- INSERT (can vary from 10s to 10,000s of records):
INSERT INTO MyTable
SELECT @fixedValue, id2, col1, col2 FROM AnotherTable
Bu ek, yalnızca bellek tablosunda yer alıyorsa son derece hızlı olmalıdır. Bununla birlikte, disk tabanlı bir tablo da içerir ve bununla ilişkili tüm kilitleme ve engellemeye tabidir. Böylece, burada gerçek zamanlı atık disk tabanlı tablo üzerinde.
Verileri belleğe yükledikten sonra disk tabanlı tablodan 100.000 satır ekine karşı hızlı bir test yaptığımda - ikinci yanıt süreleri oldu. Ancak, verilerinizin çoğu yalnızca 20 saniyeden daha kısa bir süre için saklanır. Bu gerçekten önbellekte yaşamak için fazla zaman vermez. Ayrıca AnotherTable
gerçekte ne kadar büyük olduğundan emin değilim ve değerlerin diskten okunup okunmadığını bilmiyorum. Bu cevaplar için size güvenmeliyiz.
Seçim sorgusu ile:
SELECT id2, col1
FROM MyTable INNER JOIN OtherTbl ON MyTable.id2 = OtherTbl.pk
WHERE id1 = @value
ORDER BY col1
Yine, birlikte çalışma + disk tabanlı tablo performansının merhametindeyiz. Ayrıca, HASH dizinlerinde türler ucuz değildir ve kümelenmemiş bir dizin kullanılmalıdır. Bu, yorumlarda bağladığım Dizin kılavuzunda çağrılır .
Bazı gerçek araştırma tabanlı gerçekleri vermek için SearchItems
, bellek tablosuna 10 milyon satır ve AnotherTable
100.000 ile yükledim, çünkü gerçek boyutunu veya istatistiklerini bilmiyordum. Daha sonra yürütmek için yukarıdaki seçme sorgusunu kullandım. Ayrıca wait_completed üzerinde genişletilmiş olaylar oturumu oluşturdum ve bir halka arabelleğe koydu. Her çalıştırmadan sonra temizlendi. Ayrıca, tüm verilerin bellekte yerleşik olmayabileceği DBCC DROPCLEANBUFFERS
bir ortamı simüle etmeye çalıştım .
Sonuçlar, boşlukta bakıldığında muhteşem bir şey değildi. Bunu test ettiğim dizüstü bilgisayar daha yüksek sınıf SSD kullandığından, kullandığım VM için yapay olarak disk tabanlı performansı düşürdüm.
Yalnızca bellek tabanlı tablodaki sorgunun 5 çalıştırılmasından sonra (birleştirme ve alt sorguları kaldırmadan) sonuçlar bekleme bilgisi olmadan geldi. Bu beklendiği gibi.
Orijinal sorguyu kullanırken, ancak, bekledim. Bu durumda veriler diskten okunurken mantıklı olan PAGEIOLATCH_SH idi. Bu sistemdeki tek kullanıcı olduğum ve ekler, güncellemeler, birleştirilmiş tabloya karşı silmeler için büyük bir test ortamı oluşturmak için zaman harcadığım için herhangi bir kilitleme veya engellemenin yürürlüğe girmesini beklemiyordum.
Bu durumda, zamanın önemli bir kısmı disk tabanlı tabloya harcandı.
Son olarak silme sorgusu. Yalnızca ID1 tabanlı satırları bulmak, bir dizin ile son derece verimli değildir. Eşitlik tahminlerinin karma indeksleri için uygun olduğu doğru olsa da, verilerin düştüğü bölüm tüm karma sütunları temel alır. Bu nedenle id1, id2, burada id1 = 1, id2 = 2 ve id1 = 1, id2 = 3, karma (1,2) ve (1,3) arasında olacağından farklı bölümlere ayrılır. Karma dizinleri aynı şekilde yapılandırılmadığından, bu basit bir B-Ağacı aralığı taraması olmaz. Daha sonra bunun bu işlem için ideal bir dizin olmasını beklemezdim, ancak daha büyük boyutta siparişleri daha uzun süre almasını beklemem. Ben wait_info bu konuda ilgilenen olacaktır.
En önemlisi, Microsoft'un reklamını yaptığı kilitsiz mimari göz önüne alındığında, yüksek eşzamanlılık senaryolarında süper bir avantaj elde etmeyi umuyordum. Bunun yerine, en kötü performanslar tam olarak masada birkaç sorgu çalıştıran birkaç eşzamanlı kullanıcı olduğunda gerçekleşir.
Kilitlerin mantıksal tutarlılık için kullanıldığı doğru olsa da, işlemler hala atomik olmalıdır. Bu, özel bir CPU tabanlı karşılaştırma operatörü aracılığıyla yapılır (bu nedenle In-Memory yalnızca belirli [son 4 yılda yapılan tüm cpuslar da olsa) işlemcilerle çalışır). Bu yüzden her şeyi ücretsiz olarak almıyoruz, bu işlemleri tamamlamak için hala biraz zaman olacak.
Ortaya konması gereken bir başka nokta, neredeyse tüm sorgularda kullanılan arayüzün, en az bir disk tabanlı tabloya dokunan T-SQL (ve doğal olarak derlenmiş SPROC'lar değil) olmasıdır. Bu yüzden, sonuçta, disk tabanlı tabloların performansıyla hala sınırlı olduğumuz için aslında herhangi bir performansımızın olmadığına inanıyorum.
Takip et:
Wait_completed için genişletilmiş bir etkinlik oturumu oluşturun ve bildiğiniz bir SPID'yi belirtin. Sorguyu çalıştırın ve çıktıyı bize verin veya dahili olarak tüketin.
Bize # 1'in çıktısı hakkında bir güncelleme verin.
Karma indeksleri için kova sayısını belirlemek için sihirli bir sayı yoktur. Temel olarak kovalar tamamen dolmadığı ve sıra zincirleri 3 veya 4'ün altında kaldığı sürece, performans kabul edilebilir kalmalıdır. Bu, "Günlük dosyamı neye ayarlamalıyım?" - işlem başına, veritabanı başına, kullanım türüne bağlı olacaktır.
OPTION(OPTIMIZE FOR UNKNOWN)
(bkz. Tablo İpuçları )?