SQL Server PrimaryKey, Uniqueidentifier vs INT? Hakkında

361 views
Skip to first unread message

hasan ÇAKMAK

unread,
May 17, 2017, 4:59:09 AM5/17/17
to altdotne...@googlegroups.com

Merhabalar,

 

Hali hazırda 500 firmaya hizmet veren bulut tabanlı bir projemiz var. Bu projede MSSQL veritabanında birbiri ile ilişki bir çok tablo ve her geçen gün sayıları artmakta olan kayıtlar bulunmaktadır.

İlişkiler int kolonlar üzerinden sağlanmakta. Kayıt sayıları kısa sürede milyonları geçiyor ve verileri geçmiş veriler şeklinde tablolara aktarma yapmamız (ERP uygulamalarındaki devir gibi) gerekiyor.

 

Ayrıca int max değeri de bir gün bizi sıkıntıya sokacaktır. Taşıma işlemi içinde bizim daha farklı veri tipi kullanmamız gerekiyor.

 

Bu aşama uniqueidentifier kullanmak ne kadar doğru olur? Veri taşımak birleştirmek için gayet mantıklı bir tip olduğu biliyoruz fakat index konusunda bir sorun yaratır mı fikirlerinize danışmak istedim.

GUID kullanırsak da mutlaka SEQUENTIAL mı kullanmalıyız?

 

Birde verileri eski tablolara taşımak yerine SQL Server Partition Table kullanmak sizce nasıl olur?

 

Fikirlerinizi paylaşırsanız sevinirim.

 

İyi çalışmalar

Fikret AKIN

unread,
May 17, 2017, 5:03:45 AM5/17/17
to altdotne...@googlegroups.com
GUID derim, biz devir işleminde yeni db açıp son kayıtların toplamını yazıyorduk. Önce ki sene kayıtları için sene seçip ona göre ilgili db den verileri alıyordu. 

17 May 2017 11:59 tarihinde "hasan ÇAKMAK" <hsnc...@gmail.com> yazdı:

--
You received this message because you are subscribed to the Google Groups "altdotnetturkiye" group.
To unsubscribe from this group and stop receiving emails from it, send an email to altdotnetturkiye+unsubscribe@googlegroups.com.
To post to this group, send email to altdotnetturkiye@googlegroups.com.
Visit this group at https://groups.google.com/group/altdotnetturkiye.
For more options, visit https://groups.google.com/d/optout.

Burak SARICA

unread,
May 17, 2017, 9:12:23 AM5/17/17
to altdotne...@googlegroups.com
Sequential ve random guid performans açısından çok farklı. sequential tabi ki daha hızlı (gerek insertlerde gerekse veri erişiminde) Basit bir bakış açısıyla tarih bazlı sharding yapıyorsunuz sanırım. bu yüzden sequential guid ile ilerlemeniz daha faydalı olacaktır. Veriyi sequential guid ile işaretlerseniz, randomluğu kaybedeceksiniz. Yani açık şekilde ekranlar arasında ilişki için kullanmanız iyi olmayabilir, aklınızda olsun.

--

Pamir Erdem

unread,
May 17, 2017, 9:15:27 AM5/17/17
to altdotne...@googlegroups.com
http://nhibernate.info/blog/2009/03/19/nhibernate-poid-generators-revealed.html
>> email to altdotnetturki...@googlegroups.com.
>> To post to this group, send email to altdotne...@googlegroups.com.
>> Visit this group at https://groups.google.com/group/altdotnetturkiye.
>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "altdotnetturkiye" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to altdotnetturki...@googlegroups.com.
> To post to this group, send email to altdotne...@googlegroups.com.
--
Pamir Erdem

Can Kaya

unread,
May 17, 2017, 10:10:30 AM5/17/17
to altdotnetturkiye

Öncelikle guidlerin çakıştığına çok yoğun ya da büyük sistemlerde karşılaşmaktayım. Constraint yoksa şayet abi inserti basıp geçiyor. Bir de 16 bytelık her bir satır için boyutu iyice nefret ettiriyor kendisinden. Uniquelik durumu için de başka bir kolonla merge edip ona göre bir constraint koymak gibi bedelleri var. Tabi tabloya böyle bir guid var mı diye bir sorgu atıp iyi yokmuş ben bunu insert edeyim maliyetinden çekinmiyorsanız durum başka.

Biz Partition table kullanıyoruz. SQL sorgularımız optimize edilmiş durumda. Atomic işlemler yapılıyor OLTP'de. Raporlama için Secondary node'u kullanıyoruz. Bazı çok büyük raporlar için konsolidasyon makinalarımız var. Çok sürdürülebilir güvenli bir yapı tavsiye ederim. Database maintenance işlemlerini de çok kolaylaştırıyor. Tablolarda tarih alanınız varsa where condition a tarihi ekleyip sql e go diyebilirsiniz. Tarihe bağlı yedekler alınıp restore işlemi falan gani gani avantajları var. 

Yukarda belirttim GUID 16 byte. int 4 byte bigint 8 byte. Detaylar için link aşağıda.

Baya övdüm. Daha önceki yapımız her yıl db kapat yeni db aç şeklindeydi. Bizi çok üzdü. :(

Kolaylıklar...

Erhan Cakirman

unread,
May 17, 2017, 10:25:59 AM5/17/17
to altdotne...@googlegroups.com

@Hasan

 

https://github.com/twitter/snowflake

 

yada

 

https://github.com/ccollie/snowflake-net

 

bir bakmani tavsiye ederim.

 

@Can

 

Merak ettim, siz o  GUID leri sql server tarafinda mi urettiriyorsunuz ? Yamulmuyorsam Sql Server tarafinda bir kac durum soz konusuydu bu duplicate uretmelerle ilgili. Birde ID lerin database tarafindan uretilmesi konusuna oldum olasi karsiyim ama bu baska bir konu tabiki.

--

Can Kaya

unread,
May 17, 2017, 11:12:11 AM5/17/17
to altdotnetturkiye
@Erhan 
Hocam bizim durum farklıydı birbirini takip eden idleri maliye ye falan veriyorsun. Seri, sırra sayı numarası gibi sıkıntılarımız vardı. Sahada sayaclar okunuyor ona göre fatura yaratılıyor. Yani bir satır senin faturanken diğer satır benim ki ve bu iki fatura diyeyim birbirini takip etmeli diyordu maliye. 10 satırlık bir seri tablomuz vardı sürekli oradan aralık alınıp id yaratılıyordu. Zamanının teknolojisi oradan tıkanıp kalmıştı. Şimdi In-memory ne güzel giderdi o case e :)

Kesinlikle sana katılıyorum hocam bu işi dbye bırakmamak lazım. Identitity alanı yapayım o artırarak yazsın performansı öldürüyor. Çok fazla yaklaşım var bu konuyla ilgili. 

Her neyse konuyu dağıtmadan şu linki şuraya bırakayım. Konuyu dağıttıysam affola dupllcation ile ilgili bir deneyimimi aktardım diyelim :)

hasan ÇAKMAK

unread,
May 17, 2017, 2:38:44 PM5/17/17
to altdotne...@googlegroups.com

Merhabalar,


Öncelikle yanıtlarınız için çok teşekkürler.


@Can Hocam,

PartitionTable konusunu test edip detaylı araştıracağım, sadece şunu sormak istiyorum partition table olarak kullandığınız tablolardaki ortalama kayıt sayısı nedir acaba? Fikir yürütmem adına işime yarayacak o yüzden soruyorum.

 

SQL’in partition table özelliğinden ziyade GUID’a geçiş yapıp 1 yıl eskide kalmış tüm verileri aktif olmayan geçmiş tablosuna alalım diye düşünüyorduk bu durumda GUID olduğunda basit bir insert select le bile bunu yapabiliyoruz fakat int de bu maalesef mümkün değil.

 

Yapısal olarak bir çok Windows ve web servis ilgili tablolara update, select, insert atıyor bu da data çoğaldığında performans sorunu olarak bize dönüyor.  Biz düz mantık guid ‘a çevirip geçmişte kalmış dataları farklı tabloya atıp aktif tabloda hep az kayıt tutalım sorun ortadan kalksın diye düşünüyorduk. Sql partition table da bu anlama mı geliyor?

 

4 Byte 16 byte konusuna gelince açıkçası buradaki veri falan disk anlamında bizi çok üzmez ama tabiki sql perfomansı anlamında etkileri konusunda emin değilim. Stack de veya diğer okuduğum makalelerde de durum farklı değil bazılar guid diyor bazıları int, buradaki önerilere bakıyorum bir tarafta guid var bir tarafta siz int tarafındasınız açıkçası arada kaldık 😊

 

Sorduklarım üzerine biraz daha detaylandırıp konuşabilir miyiz üzerine.

 

@Erhan,

Eğer guid konusunda karar verirsek paylaştığınız kütüphaneyi derinlemesine inceleyip kullanacağız.  Performans analizlerine baktığımda çok başarılı görünüyor

 

Teşekkürler,

İyi akşamlar


17 Mayıs 2017 18:12 tarihinde Can Kaya <cank...@gmail.com> yazdı:
To unsubscribe from this group and stop receiving emails from it, send an email to altdotnetturkiye+unsubscribe@googlegroups.com.
To post to this group, send email to altdotnetturkiye@googlegroups.com.

Can Kaya

unread,
May 18, 2017, 5:08:24 AM5/18/17
to altdotnetturkiye
Hocam 940 milyonlarda tablolardan bir tanesi. Doğru yapılmış partitioning ile kayıtları doldur boşalt başka db ye aktarma arasında bir fark yok. Sorduğun sorunun cevabı evet.

Pkey olarak bigint kullanıyoruz. Bizde Tarih kolonu üzerinde partitioning var. 3 er aylık partitionlar şeklinde. Her bir partition ı sanki o partition a ait db gibi düşünebilirsin. Tüm sorgularda where conditionda tarih geziyor. Dolayısıyla partition'ı seçebiliyor adam.

Cold data olduğuna karar verilen partitionlar read only olarak işaretleniyor. Ancak önemli konu sql sorgularının optimize olmuş olması bu konu çok önemli yoksa projeye ket vurucu bir etkisi olur. Proje de bir DBA varsa o kotarır tüm bu işlemleri ancak yoksa sizin üzerinde biraz araştırma yapmanız testler yapmanız gerekebilir.

Saygılar..

hasan ÇAKMAK

unread,
May 18, 2017, 5:39:04 AM5/18/17
to altdotne...@googlegroups.com

@Can Hocam Merhaba,

 

Öncelikle veri sayısını paylaşmanız bir çok konuda bize yol gösterici oldu, bunun için özellikle teşekkür ederim.

Gece yaptığım testlerde veritabanını klonladım ve tarih üzerinden partition yaptım.  Partition yapılmış/yapılmamış db ler aynı sorguyu attığımda Execute Plan’a baktığımda  okuduğu data arasında inanılmaz farklar var yani tam bu manada sql partition bizim dediğimiz işi yapıyor zaten bunu net öğrendik yönlendirme için tekrar teşekkür ederim.

 

Şimdi soracağım şu, şuan ki veriler üzerinden 3 aylık bölümler şeklinde partition oluşturduk, daha sonra üzerine 6 aylık yeni data geldi diyelim her üç ayda bir yeniden partition yani sürekli bölümle nasıl yapılacak açıkçası modifie parttion gibi bir durum tam göremedim.

 

Bunun dışında ikinci bir durumsa bizde tablolarda 2 farklı tarih var birisi eklenme tarihi diğeri ise belge tarihi. UI tarafında ise opsiyonel olarak ister belge tarihinden isterse eklenme tarihi üzerinden sorgular atıyor. Bu durumda ben insertdate e göre bölsem fakat kullanıcı belge tarihine göre sorgu atsa durum nasıl şekilleniyor, yada 1 den fazla kolon üzerinden bölümle durumu söz konusu mu?

 

Ve Son olarak aynı tablolara tarih bazlı değil sadece guid bir değer üzerinden var mı yok mu sorgusu atılıyor atılması gerekiyor (Partition’a eklenmiş bir kolon değil).

Bu durumda sorguladığı veri aslında her zaman tabodaki tüm veri yani sizin adetinizle 900 milyon olmuyor mu? Burada bir öneriniz olur mu?

 

Not olarak şunu belirteyim, bütün müşterilerin verileri AccountID üzerinden ayrılıp aynı tablolarlar da tutuluyor.

 

Teşekkürler

İyi çalışmalar


18 Mayıs 2017 12:08 tarihinde Can Kaya <cank...@gmail.com> yazdı:
To unsubscribe from this group and stop receiving emails from it, send an email to altdotnetturkiye+unsubscribe@googlegroups.com.
To post to this group, send email to altdotnetturkiye@googlegroups.com.

Can Kaya

unread,
May 18, 2017, 8:12:46 AM5/18/17
to altdotnetturkiye
Şimdi soracağım şu, şuan ki veriler üzerinden 3 aylık bölümler şeklinde partition oluşturduk, daha sonra üzerine 6 aylık yeni data geldi diyelim her üç ayda bir yeniden partition yani sürekli bölümle nasıl yapılacak açıkçası modifie parttion gibi bir durum tam göremedim.

Modify işlemi data boyutuna bağlı olarak çok üzer. Planlı olmak lazım. Korkulacak bir durum yok. En kötü senaryoda datalar son partitionda birikecektir. Her yılı/3 ayı eklemelisin partitiona. Tamamen yiğit yoğurt ilişkisi. Bana soracak olursan ben son 5 yılı partition'da tutuyorum daha eskilerin hepsini tek bir partitiona attım. Cold data. Yatıyor. Partition sayım hiç artmıyor yani. Eski cold dataya gidiyor. Yeni 3 ay için partiiton açılıyor. Belki sana da uyabilir bu yapı.

Bunun dışında ikinci bir durumsa bizde tablolarda 2 farklı tarih var birisi eklenme tarihi diğeri ise belge tarihi. UI tarafında ise opsiyonel olarak ister belge tarihinden isterse eklenme tarihi üzerinden sorgular atıyor. Bu durumda ben insertdate e göre bölsem fakat kullanıcı belge tarihine göre sorgu atsa durum nasıl şekilleniyor, yada 1 den fazla kolon üzerinden bölümle durumu söz konusu mu?

Partitioning tabloyu yatay olarak böldüğü için tek kolon kullanmak makbuldur. Persisted column yapıp iki değeri kullanarak bir kolon yapılıp o da kullanılabilir ancak hiç tavsiye edilmez. [Info]Conversion maliyeti efsane olur.

Indexlemeyle çözülecek şeyler. Sende customerId alanı olduğu için çok daha şanslısın. Ciddi bir eliminasyon yapacaktır. Hatta customerId, CreateDate UpdateDate tarihlerine bir nonclustered index atılabilir. [Info]Fill factor değeri önemli, ColumnStore gibi kavramlarda çokca işini görebilir. 

Tablo yapın bence çok uygun ben de aynısını yapardım :)

Kolaylıklar.

Saygılar...
Reply all
Reply to author
Forward
0 new messages