MySQL - neden her alanı indekslemiyorsunuz?


107

Son zamanlarda indekslerin harikasını öğrendim ve performans önemli ölçüde gelişti. Ancak, öğrendiklerime rağmen bu sorunun cevabını bulamıyorum.

Dizinler harika, ama neden birisi tabloyu inanılmaz derecede hızlı hale getirmek için tüm alanları dizine ekleyemiyor? Eminim bunu yapmamak için iyi bir neden vardır, ama otuz alanlı bir tabloda üç alana ne dersiniz? 30 alanda 10 mu? Çizgiyi nereye çekmeli ve neden?


7
Dizine alınmış 10.000'den fazla giriş içeren bir tabloya bir değer eklemeyi deneyin, tüm girişler ekleme / silme nedeniyle güncellenmelidir ve bu, her bir değerin bir dizini varsa, büyük bir zaman yükü ve bir miktar bellek ek
yüküdür

5
Alan ve yazma performansının yanı sıra bir neden daha var: tek bir tablo erişimi için birden çok dizin kullanmak çok verimsizdir . Bu, her bir sütunda bir dizininiz olsa bile, WHERE yan tümcesinde birden çok sütuna erişildiğinde seçme performansının çok iyi olmadığı anlamına gelir. Bu durumda, çok sütunlu bir dizin en iyisidir.
Markus Winand

1
30 alanlı bir masanız varsa, tablo yapılarınıza gerçekten bakmalısınız. Birlikte çalışmak çok zor olmalı.
ağlar

Yanıtlar:


122

Dizinler bellekte (RAM) yer kaplar; Çok fazla veya çok büyük dizin ve DB bunları diske veya diske takas etmek zorunda kalacak. Ayrıca, ekleme ve silme süresini de artırır (her dizin, eklenen / silinen / güncellenen her veri parçası için güncellenmelidir).

Sonsuz hafızanız yok. Bunu tüm dizinlerin RAM'e sığması için yapmak = iyi.

Sonsuz zamanınız yok. Yalnızca indekslemeniz gereken sütunların indekslenmesi, ekleme / silme / güncelleme performans isabetini en aza indirir.


11
Genel bir anlayış sağlamak için güzel ve rahat bir cevap, ancak dizinlerdeki çizginin nereye çekileceğini belirlemede pek yardımcı olmuyor. Nasıl bilebilirsin Bunları yalnızca WHERED alanlarına ekleyip en iyisini mi umuyorsunuz?
Andrew

@Andrew bir buçuk yıl sonra sorunuzun cevabını buldunuz mu?
Sinjai

1
@Sinjai Bunları genellikle nerede olan sütunlara eklemek muhtemelen iyi bir kuraldır. Ancak aksi takdirde, endeksler konusunda uzmanlaşmak istiyorsanız çok fazla okuma yapabilirsiniz. Örneğin. stackoverflow.com/questions/3049283/…
Andrew

Disk alanını unutmayın.
jpmc26

27

Bir satır her güncellendiğinde, eklendiğinde veya silindiğinde her dizinin güncellenmesi gerektiğini unutmayın. Yani ne kadar çok dizine sahip olursanız, yazma işlemleri için o kadar yavaş performansa sahip olursunuz.

Ayrıca, her dizin daha fazla disk alanı ve bellek alanı (çağrıldığında) kullanır, bu nedenle okuma işlemlerini de potansiyel olarak yavaşlatabilir (büyük tablolar için). Şuna bak


6
Bağlantı MS SQL Server içindir ; bu soru MySQL için
OMG Ponies

5
@OMG bağlantıdaki noktaların çoğu tüm büyük RDBMS için geçerlidir
RichardTheKiwi

5
@Richard aka cyberkiwi: Dizinler ANSI kapsamında değildir - her satıcının benzer terminolojiyi kullanması bir mucize. Ancak o zaman bile, yalnızca SQL Server ve MySQL "kümelenmiş" ve "kümelenmemiş" indeksi kullanır - bu, SQL Server'da MySQL'den daha fazlasını ifade eder. Bir satıcıya yönelik tavsiyelerin diğerine uygulanması gerektiğini garanti edecek hiçbir şey yoktur.
OMG Ponies

3
@omg ilk 6 puan herhangi bir DBM için geçerlidir. kümelenmemiş / kümelenmemiş olanları atlayın, ardından aşağıya genel indeksleme ile ilgili daha fazla nokta, yine noktada. Belirtmek istediğiniz belirli şeyler varsa, onları arayın. Aksi takdirde, yorumlardan (silinmiş yanıtınız dahil) hiç kimsenin değerlendirmenize katılmadığı tüm yanıtları reddediyorsunuz gibi görünüyor.
RichardTheKiwi

10

CRUD ihtiyaçlarını dengelemelisiniz. Tablolara yazmak yavaşlar. Çizginin nereye çizileceğine gelince, bu verilere nasıl erişildiğine bağlıdır (sıralama filtreleme, vb.).


ve ayrıca her dizin bir miktar veritabanı alanı kaplar
Acanthus

@Acanthus: Mevcut en küçük sabit diskler gigabayt cinsinden ölçülür .
OMG Ponies

4
@OMG ama Brian'ın belirttiği gibi RAM değil. öyle asla gereğinden fazla fazla mağazaya iyi bir fikir. RAM'de veri / dizin önbelleğe alma, yedekleme ortamı (bant başına sığacak sürümler vb.), işe yaramaz dizinlerden etkilenir
RichardTheKiwi

9
Bir kaynağın bolluğu, israf veya verimsizlik için bir neden değildir.
Smandoli

6
Doğru, ancak kısıtlamalar 10+ yıl önceki gibi değil.
OMG Midilli

2

İndeksleme, hem sürücüden hem de ramdan daha fazla ayrılmış alan kaplayacak, aynı zamanda performansı da çok artıracaktır. Ne yazık ki bellek sınırına ulaştığında, sistem sürücü alanını teslim edecek ve performansı riske atacaktır. Pratik olarak, ne ekleme ne de arama (WHERE cümlesi) gibi herhangi bir veri geçiş algoritmasında içermediğini düşündüğünüz hiçbir alanı indekslememelisiniz. Ama aksi takdirde yapmalısın. Varsayılan olarak tüm alanları endekslemeniz gerekir. Dizini kaldırmayı düşünmeniz gereken alanlar, sorguların yalnızca moderatör tarafından kullanılmasıdır, hıza da ihtiyaç duymadıkları sürece


2

bu cevap kişisel fikrimdir, cevaplamak için matematiksel mantığımı kullanıyorum

ikinci soru, nerede durulacağıyla ilgiliydi, Önce matematiksel bir hesaplama yapalım, bir tabloda L alanlı N satırımız olduğunu varsayalım, eğer tüm alanları indekslersek, her tablonun sıralanacağı bir L yeni indeks tabloları alacağız. yani indeks alanındaki veriler, ilk bakışta tablonuz W ağırlık ise W * 2 (1 tera 2 tera olacak) 100 büyük masanız varsa (tablo numarasının olduğu projede zaten çalıştım) 1800 masa civarında) bu alanın 100 katını (100 tera) boşa harcarsınız, bu akıllıca olmaktan çok uzaktır.

Dizinleri tüm tablolara uygulayacaksak, dizin güncellemelerini tek bir güncellemenin tüm dizinlerin güncellemesini tetiklediğini düşünmemiz gerekecek, bu, zaman içinde tüm sırasız eşdeğerleri seçmektir.

Bundan, bu senaryoda, eğer bu zamanı kaybederseniz, bir seçimde veya bir güncellemede kaybetmenin tercih edileceği sonucuna varıyorum, çünkü dizine alınmamış bir alanı seçerseniz, tüm alanlarda başka bir seçimi tetiklemeyeceksiniz. endekslenmemiş

ne endekslenmeli?

yabancı anahtarlar: temel alan bir zorunluluktur

birincil-anahtar: Birinin okuyup okuyamayacağından henüz emin değilim, bu vakada yardımcı olabilir

diğer alanlar: ilk doğal cevap, kalan fild'lerin yarısıdır neden: Daha fazla indekslemeniz gerekiyorsa, en iyi cevaptan çok uzak değilsiniz, eğer daha az indekslemeniz gerekiyorsa, aynı zamanda uzakta değilsiniz çünkü hiçbir indeksin kötü olmadığını ve tümünün indekslendiğini biliyoruz aynı zamanda kötü.

Bu 3 noktadan, K anahtarlarından oluşan L alanlarımız varsa, sınırın ((L-K)/2)+KL / 10 kadar aşağı yukarı bir yerde olması gerektiği sonucuna varabilirim.

bu cevap mantığıma ve kişisel tercihlerime dayanmaktadır


1

Bir tablodaki tüm sütunları indekslemek iyi bir fikir değildir. Bu, tabloyu okumayı çok hızlı hale getirirken, aynı zamanda yazmak da çok daha yavaş hale gelir. Her sütunun indekslendiği bir tabloya yazmak, yeni kaydı bu tabloya koymayı ve ardından her sütunun bilgilerini kendi indeks tablosuna koymayı içerir.


Tabloyu şimşek hızında okumayı sağlayıp sağlamayacağından emin değilim, özellikle de veri tablosu sadece 100MB ancak indeks. Tablo 300MB veya daha fazla ise.
David

Söylediğin her şey daha önce ifade edildi.
Vael Victus
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.