VARCHAR ve INTEGER alanlarının anahtarlardaki farkları
Tablolarımda birincil anahtar olarak tamsayı ID’ler kullanıyorum. Bunun yerine varchar alanlar kullanırsam ne olur? Bu durumda, özellikle büyük tablolar için performans kaybı yaşar mıyım? Birleştirmeler (joins) tamsayı sütununda olduğu kadar hızlı çalışmaya devam eder mi?
Varchar veya tamsayı kullanmanız durumunda performansınız yaklaşık olarak aynı olmalıdır. Firebird indeks anahtarlarını her zaman bayt bazında karşılaştırır ve değerin yalnızca anlamlı kısmı saklanır.
Tek alanlı bir anahtar önce üç kanonik türden birine dönüştürülür: harmanlamalı (collation) dize, çift duyarlıklı (double precision) ve (maalesef) 64 bit tamsayı. Tarihler çift duyarlıklı kayan nokta sayılarına dönüştürülür.
Bayt değerinden farklı bir harmanlamaya sahip dizeler, harmanlama biçimlerine dönüştürülür. Bu biraz kara sanattır ve dizenin boyutunu genişletir, ancak sonuç olarak dize, aynı harmanlamadaki diğer dizelerle sıralandığında doğru yerini bulur. ‘A’, ‘a’, ‘â’, ‘á’, ‘Ă’, ‘ã’, ‘ä’, ‘å’, ‘ă’, ‘ą’, ‘Ā’ hepsi belirlenmiş yerlerinde görünür. (E-posta istemcinize yaptığı şey için üzgünüm …. benimkinde bunlar ‘A’nın on bir çeşididir.) Sondaki boşluklar anahtara dahil edilmez.
Çift duyarlıklı sayı, bayt bazında sıralanacak şekilde karıştırılır - kabaca işareti, ardından üssü, ardından mantisi ters çevirir ve sondaki sıfırları keser.
Bilgisayardaki 64 bit tamsayıların endianness’ine bağlı olarak, onlar da bayt bazında karşılaştırılacak şekilde karıştırılır. Bu bir optimizasyon kaybı gibi görünebilir, ancak indeks anahtarları doğal sınırlarda saklanmaz ve önek sıkıştırmasına tabi tutulurlar, bu nedenle bayt bayt karşılaştırmadan daha büyük bir karşılaştırma kullanmanın bir yolu yoktur.
Bileşik anahtarlar da hemen hemen aynıdır. Her parça kendi indeks anahtar türüne dönüştürülür ve 4 baytın katına dolgulanır. Her dört bayttan sonra Firebird, anahtarın mevcut alanının konumunu içeren bir bayt ekler. Böylece LastName, FirstName, ZodiacSign üzerindeki bir indeks 1Harr1ison2Ann 3Gemi3ni olarak ortaya çıkar. Bu, Damnation ile Dam nation’ı karıştırma utancını önler.
Yukarıda neden “(maalesef)” dedim? Çünkü sayılar için tek bir biçime sahip olmak, Firebird’ün indeksleri yeniden oluşturmadan sayıların boyutunu değiştirmesine olanak tanır. Ancak Borland 64 bit tamsayıları geri eklediğinde - InterBase’in Vax’larda en başından beri 64 bit tamsayıları vardı - bazı parlak zekalı kişi, çift duyarlıklı sayıların 56 bit hassasiyete sahip olduğunu ve 64 bit tamsayıların 64 bit olduğunu fark etti. Öte yandan, Firebird indeksleri bir miktar hassasiyetsizliği işleyecek şekilde tasarlanmıştır … veya kalan 8 bit sona eklenebilir … neyse. Bu yüzden Numeric/Decimal 9’dan Numeric/Decimal 12’ye geçerken indeksleri yeniden oluşturmanız gerekir. Üzücü.
“Önek sıkıştırması?” Bir sayfada ilk olmayan veya bir atlamadan sonraki ilk olmayan bir anahtarı saklarken Firebird önceki anahtara bakar ve bir sonraki anahtarın başlangıcının öncekiyle aynı olan kısmını keser ve kesilen kısmın uzunluğunu başa ekler. Böylece “AAAA”, “AAAB”, “AAAC”, “AABC” dizeleri şu hale gelir:
“AAAA”, “3B”, “3C” ve “2BC”. Bazı GUID biçimlerinde, sayının değişken kısmının önce, sabit kısmın sonra gelmesi gibi bir sorun vardır. Bu, önek sıkıştırmasını bozar ve indekslerin boyutunu şişirir.
“Atlama?” - Önek sıkıştırması indekslerin boyutunu çok azaltır, G/Ç’yi azaltır, ancak anahtarı çözmek için tüm sayfa boyunca okumayı gerektirir. 1K sayfalarla sorun değil, ancak daha büyük sayfa boyutlarında hesaplama kabul edilemezdi. Bu nedenle her indeks sayfasının artık sıkıştırılmamış girdilerin ofsetlerini gösteren kendi indeksi vardır. Bu indekse atlama vektörü (jump vector) denir.
Ann Harrision