Neden gerekli?
Veriler disk tabanlı depolama aygıtlarında depolandığında, veri blokları olarak saklanır. Bu bloklara bütünüyle erişilerek atomik disk erişim işlemi yapılır. Disk blokları, bağlantılı listelerle aynı şekilde yapılandırılmıştır; her ikisi de veri için bir bölüm, bir sonraki düğümün (veya bloğun) konumunu gösteren bir işaretçi içerir ve her ikisinin de bitişik olarak depolanması gerekmez.
Bir dizi kaydın yalnızca bir alanda sıralanabilmesi nedeniyle, sıralanmamış bir alanda arama yapmanın N/2
blok N
erişimi (ortalama) gerektiren Doğrusal Arama gerektirdiğini (ortalama olarak), masa açık. Bu alan anahtar olmayan bir alansa (başka bir deyişle benzersiz girişler içermiyorsa), N
blok erişimlerinde tablo alanının tamamı aranmalıdır .
Sıralı bir alanla birlikte, log2 N
blok erişimi olan bir İkili Arama kullanılabilir . Ayrıca, veriler anahtar olmayan bir alana göre sıralandığından, daha yüksek bir değer bulunduğunda tablonun geri kalanının yinelenen değerler için aranması gerekmez. Böylece performans artışı büyüktür.
Endeksleme nedir?
Dizin oluşturma, birden çok alanda birkaç kaydı sıralamanın bir yoludur. Tablodaki bir alanda dizin oluşturmak, alan değerini tutan başka bir veri yapısı ve ilişkili kayıt için bir işaretçi oluşturur. Bu indeks yapısı daha sonra, Binary Search'lerin üzerinde yapılmasına izin verilerek sıralanır.
Endekslemenin dezavantajı, endekslerin MyISAM motorunu kullanan bir tabloda birlikte depolandığından, bu endekslerin diskte ek alan gerektirmesidir, aynı tablodaki birçok alan dizine eklendiğinde bu dosya temel dosya sisteminin boyut sınırlarına hızla ulaşabilir .
O nasıl çalışır?
İlk olarak, örnek bir veritabanı tablosu şemasının ana hatlarını çizelim;
Alan adı Veri türü Diskteki boyut
id (Birincil anahtar) İmzasız INT 4 bayt
firstName Karakter (50) 50 bayt
lastName Karakter (50) 50 bayt
Adres Char (100) 100 bayt
Not : char, disk değerinde doğru bir boyuta izin vermek için varchar yerine kullanılmıştır. Bu örnek veritabanı beş milyon satır içerir ve dizinsizdir. Şimdi birkaç sorgunun performansı analiz edilecektir. Bunlar id (sıralanmış anahtar alanı) ve firstName (anahtar olmayan sıralanmamış alan) kullanan bir sorgudur .
Örnek 1 - sıralanmamış alanlara göre sıralanmış
r = 5,000,000
Sabit bir boyuttaki kayıtların örnek veritabanımıza göre, kayıt uzunluğu R = 204
bayt verir ve bunlar varsayılan blok boyutu B = 1,024
baytlarını kullanan MyISAM motoru kullanılarak bir tabloda saklanır . Tablonun engelleme faktörü bfr = (B/R) = 1024/204 = 5
disk bloğu başına kayıt olacaktır . Tabloyu tutmak için gereken toplam blok sayısı N = (r/bfr) = 5000000/5 = 1,000,000
bloktur.
Kimlik alanındaki bir doğrusal arama, id alanının N/2 = 500,000
anahtar bir alan olduğu göz önüne alındığında, bir değer bulmak için ortalama bir blok erişimi gerektirir. Ancak kimlik alanı da sıralandığından, ortalama log2 1000000 = 19.93 = 20
blok erişimi gerektiren bir ikili arama gerçekleştirilebilir . Anında bunun ciddi bir gelişme olduğunu görebiliriz.
Artık firstName alanı ne sıralanmış ne de anahtar alandır, bu nedenle ikili bir arama imkansız değildir ve benzersiz değerler değildir ve bu nedenle tablo, tam bir N = 1,000,000
blok erişimi için sonuna kadar arama yapmayı gerektirecektir . Endekslemenin düzeltmeyi amaçladığı durum budur.
Bir dizin kaydının yalnızca dizinlenmiş alanı ve orijinal kaydın işaretçisini içerdiği göz önüne alındığında, işaret ettiği çok alanlı kayıttan daha küçük olacağı anlamına gelir. Bu nedenle dizinin kendisi orijinal tablodan daha az disk bloğu gerektirir, bu nedenle yineleme için daha az blok erişimi gerektirir. FirstName alanındaki bir dizinin şeması aşağıda özetlenmiştir;
Alan adı Veri türü Diskteki boyut
firstName Karakter (50) 50 bayt
(kayıt işaretçisi) Özel 4 bayt
Not : MySQL'deki işaretçiler tablonun boyutuna bağlı olarak 2, 3, 4 veya 5 bayt uzunluğundadır.
Örnek 2 - Dizinleme
r = 5,000,000
Endeks kaydı uzunluğu R = 54
bayt ve varsayılan blok boyutu B = 1,024
bayt kullanan kayıt örnek veritabanımız verildi . Dizinin engelleme faktörü, bfr = (B/R) = 1024/54 = 18
disk bloğu başına kayıt olacaktır . Dizini tutmak için gereken toplam blok sayısı N = (r/bfr) = 5000000/18 = 277,778
bloktur.
Artık firstName alanını kullanan bir arama, performansı artırmak için dizini kullanabilir. Bu, ortalama log2 277778 = 18.08 = 19
blok erişimi olan dizinin ikili aramasına izin verir . Okumak için daha fazla blok erişimi gerektiren gerçek blok adresini bulmak için toplam erişimi blok erişimine getirerek, dizinlenmemiş tabloda 19 + 1 = 20
bir firstName eşleşmesi bulmak için gereken 1.000.000 blok erişiminden çok daha fazla ağlama gerekir .
Ne zaman kullanılmalıdır?
Bir dizin oluşturmanın ek disk alanı gerektirdiği (yukarıdaki örnekten 277.778 blok daha fazla, ~% 28 artış) ve çok fazla endeksin dosya sistemleri boyut sınırlarından kaynaklanan sorunlara neden olabileceği göz önüne alındığında, doğru seçimi seçmek için dikkatli düşünülmelidir dizine eklenecek alanlar.
Endeksler yalnızca kayıtlar içinde eşleşen bir alanı aramayı hızlandırmak için kullanıldığından, yalnızca çıktı için kullanılan indeksleme alanlarının bir ekleme veya silme işlemi yaparken basitçe bir disk alanı ve işlem süresi kaybı olması ve dolayısıyla kaçınılmalıdır. İkili bir araştırmanın doğası da dikkate alındığında, verilerin kardinalitesi veya tekliği önemlidir. Kardinalitesi 2 olan bir alanda endeksleme, verileri ikiye bölerken, 1.000'lik bir kardinalite yaklaşık 1.000 kayıt döndürür. Böyle düşük bir kardinalite ile etkinlik doğrusal bir sıraya indirgenir ve kardinalite kayıt numarasının% 30'undan azsa, sorgu optimize edici endeksi kullanmaktan kaçınır ve endeksi etkin bir şekilde alan kaybı haline getirir.