Veritabanı dizinleriyle izlenecek en iyi uygulamalar [kapalı]


17

Dizin kullanarak veritabanı performansını artırmak için bazı DO ve DONT'lar nelerdir?

DO, bir dizinin oluşturulması gereken bir durum veya performansı artıracak başka bir dizinle ilgili ipucu olacaktır.

DONT, bir dizin oluşturulmaması gerektiğinde veya performansa zarar verebilecek başka bir dizinle ilgili eylem olduğunda ortaya çıkar.


3
profili, profili, profili
GrandmasterB

Yanıtlar:


15

Bu, kısmen veritabanının ne için kullanılacağına bağlıdır, çünkü genel olarak dizinler eklemeleri ve güncellemeleri yavaşlatır ve sorguları hızlandırır. Bir veri ambarında, genellikle dizinler oluşturmayı kolaylaştıran güncellemeler ve toplu ekler ve birçok dizinle hızlanan çok sayıda sorgu vardır. Web satışları ve benzerleri için çevrimiçi bir veritabanında, çok sayıda ek ve güncelleme vardır, bu nedenle dikkatlice seçilmiş birkaç dizinden daha fazlası, onu yavaşlatır.

Belirli bir türde çok fazla sorgu alırsanız, veri ambarlarından daha çok çevrimiçi işlem için daha fazla olsa da, sorgu için bir dizin oluşturabilirsiniz. Belirli sütunlar sorgularda çok fazla gelirse, bu sütun üzerinde bir dizin isteyebilirsiniz ve bu özellikle birçok farklı ve genellikle öngörülemeyen şekilde sorgulanan veri ambarları için yararlıdır.

Bir dizin eklediğinizde veya kaldırdığınızda, ne gibi bir etkisi olduğunu görmek için bir performans testi yapmaya çalışın. Bu olmadan, kör vuruyorsun.

Sorguları ve veritabanlarını ayarlama üzerine, genellikle bir veritabanı sistemine özgü ve bu RDBMS araçlarını kullanan kitaplar vardır. Veritabanını çok fazla optimize etmeniz gerektiğini düşünüyorsanız, büyük bir işlem yürütüyorsunuzdur ve muhtemelen uygun uzmanlığa sahip bir DBA kiralamanız gerekir.


17

Bu, tablolarınızı nasıl kullandığınıza bağlıdır. Tek ve basit bir cevap yok.

Size verebileceğim en iyi tavsiye: bir ayarlama danışmanı kullanmak . Uygulamayı kullanırken veritabanı komutlarını analiz edecekler, daha sonra size anlamlı öneriler sunmak için yük testleri yapacaklardır.

Onlar için var SQL Server & Oracle . Diğer DBMS onlara sahip olup olmadığını bilmiyorum, sadece onlar böyle temel araçlar sağlamak şüphe.

Birkaç rastgele tavsiye:

  • Dizinler, genellikle WHERE yan tümcesinde yer alan sütunlara uygulandığında yüksek performans artışı sağlar
  • Sorgularınızda en çok kullanılan sütun için Kümelenmiş dizin kullanın.
  • Sütun kombinasyonuyla birden çok dizin oluşturabileceğinizi unutmayın (sorgularınızda kullanıldıkları için)
  • Çok sayıda dizine sahip olmak INSERT komutlarının performansını azaltır.

Son tavsiye : DB performansları projeniz için gerçekten önemliyse, bir uzman kiralayın. Ben de öyle yaptım.


2
Sütun kombinasyonlarındaki dizinler için +1. Sütunlarda endeksler ave bolduğu değil bir endeks olarak aynı (a, b). İkincisi neredeyse üzerinde endeksi olarak iyi gibidir abir durumla sorguları hızlandırmak için a, üzerinde kitlesel iyi koşullarla sorguları içindir ave bve üzerinde sorgular için kullanışlı değildir byalnız. (Çoğu veritabanı bunu kullanmayacaktır. Oracle, düzenli olarak yaptığı kilometreyi
alamaz

2
+1, "sorgu planlarını okumayı öğrenin, böylece ne endeksleyeceğinizi bileceksiniz"
Steven A. Lowe

4

@Pierre 303 zaten söyledi, ama tekrar söyleyeceğim. DO sütunların kombinasyonları endeksleri kullanın. A kombine endeks (a, b)sadece biraz daha yavaş sorgulamaları içindir aüzerinde bir dizin daha ayalnız ve sorgu iki sütunu birleştiren daha iyi kitlesel olduğunu. Bazı veritabanları tablo üzerinde ave böncesinde dizinleri birleştirebilir , ancak bu neredeyse birleşik bir dizine sahip olmak kadar iyi değildir. Birleştirilmiş bir dizin oluşturduğunuzda, ilk olarak büyük olasılıkla aranan sütunu birleştirilmiş dizine koymalısınız.

Veritabanınız destekliyorsa, sütunlar yerine sorgularda gösterilen işlevlere dizinler YAPIN . (Bir sütunda işlev çağırıyorsanız, o sütundaki dizinler işe yaramaz.)

Eğer (örneğin PostgreSQL, MySQL, ancak oluşturmak ve anında yok edebilir doğrudur geçici tablolarla bir veritabanı kullanıyorsanız değil Oracle), sonra DO geçici tablolarda dizinler oluşturun.

Bunu sağlayan bir veritabanı (örneğin Oracle) kullanıyorsanız, DO iyi sorgu planlarında kilit. Sorgu iyileştiricileri zaman içinde sorgu planlarını değiştirir. Genellikle planı geliştirirler. Ama bazen bunu daha da kötüleştiriyorlar. Genellikle plan iyileştirmelerini gerçekten fark etmezsiniz - sorgu bir darboğaz değildi. Ancak tek bir kötü plan yoğun bir siteyi yıkabilir.

DO DEĞİL Üzerinde büyük bir veri yükü yapmak üzereyiz tabloları endeksler var. Dizinleri düşürmek, verileri yüklemek ve ardından dizinleri tabloyu yüklerken korumaktan çok daha hızlıdır.

YAPMAYIN büyük bir masa, küçük bir kısmından fazlasını erişime zorunda sorgularında dizinleri kullanırlar. (Ne kadar küçük donanıma bağlıdır.% 5 iyi bir temel kuraldır.) Örneğin, ad ve cinsiyete sahip verileriniz varsa, adlar dizinleme için iyi bir adaydır, çünkü verilen herhangi bir ad toplam satırların küçük bir kısmını temsil eder. Yine de satırların% 50'sine erişmeniz gerekeceğinden cinsiyete göre dizine eklemek yararlı olmaz. Bunun yerine tam bir masa taraması kullanmak istiyorsunuz. Bunun nedeni, dizinlerin büyük bir dosyaya rasgele erişmesini sağlayarak disk aramalarına ihtiyaç duymanıza neden olmasıdır. Disk yavaş çalışıyor. Bir örnek olarak ben son zamanlarda benziyordu bir saat süren sorgu hızlandırmak başardı:

SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
  JOIN big_table
    ON big_table.small_table_id = small_table.id
GROUP BY small_table.id

aşağıdaki gibi yeniden yazarak 3 dakikadan daha kısa bir sürede:

SELECT small_table.id, big_table_summary.summed_value
FROM small_table
  JOIN (
      SELECT small_table_id, SUM(some_value) as summed_value
      FROM big_table
      GROUP BY small_table_id
    ) big_table_summary
    ON big_table_summary.small_table_id =  small_table.id

Bu da veritabanını cazip dizini kullanmaya çalışmaması gerektiğini anlamaya zorladı big_table.small_table_id. (Oracle gibi iyi bir veritabanı kendi başına bunu çözmelidir. Bu sorgu MySQL üzerinde çalışıyordu.)

Güncelleme: İşte yaptığım disk arama noktasının açıklaması. Bir dizin, verilerin tablodaki yerini söylemek için hızlı bir arama sağlar. Bu genellikle bir kazançtır çünkü yalnızca bakmanız gereken verilere bakacaksınız. Ama her zaman değil, özellikle de sonunda çok fazla veriye bakacaksanız. Diskler verileri iyi aktarır, ancak aramaları yavaşlatır. Diskteki verilere rastgele bir arama saniyenin 1 / 200'ü kadar sürer. Sorgunun yavaş sürümü, bunlardan 600.000 gibi bir şey yaparak yaralandı ve bir saat kadar sürdü. (Bundan daha fazla arama yaptı, ancak önbellekleme bunlardan bazılarını yakaladı.) Bunun aksine, hızlı sürüm her şeyi okumak zorunda olduğunu biliyordu ve 70 MB / saniye gibi bir veri akışı gerçekleştiriyordu. 3 dakikadan az bir sürede 11 GB'lık bir masadan geçti.


Merhaba, senin örneğinle kafam karıştı. İndeksi kullanmanın işleri daha hızlı hale getireceğini düşünürdüm, endekslerin amacı bu değil mi? Bir sorgu bir tablonun% 5'inden fazlasına erişirse, aradığınız sütunda bir dizinin bulunmasının işleri yavaşlatacağını mı söylüyorsunuz?
Upvote

@Click Upvote: Bir sorgu bir tablonun% 5'inden fazlasına erişirse (tam kesir yüksek oranda donanıma ve verilere bağımlıdır), bu sorgu için dizin kullanmamak daha hızlıdır. Bir indeks kullanmak, onu kullanmadığınız sürece zarar vermez. Bunun nedenini daha ayrıntılı olarak güncelleyeceğim.
btilly

Kullanışlı bilgi. Bu konuda daha fazla örneğin mysqlperformanceblog.com/2007/08/28/… Ama merak ediyorum, bir 'alt sorgu yapmak için gereken bu kadar' anahtar yoksay 'değil mi?
İnka

@Inca: 'Anahtarı yoksay' öğesinin farkında değildim. Veritabanlarını, genellikle farkında olmadığım veritabanına özgü şeyler olduğu kadar değiştiriyorum. İşe yarayan seslerinden, ancak nihai çözümümden önemli ölçüde daha az verimli. Aradaki fark, daha sonra gruplanacak, benimki gruplanırken katılacaktı. Bu, daha az kaydın birleştirilmesi gerektiğinden, katılma işini azaltır.
btilly

"İyi bir veritabanı (örn. Oracle, ancak MySQL değil)": Lütfen, özellikle MySQL'in aynı anda birden fazla dizini mükemmel bir şekilde kullanabileceğini göz ardı ettiğinizde, bunun gibi aptalca tanıtımlardan kaçının (sorgu planlarında "INDEX MERGE" olarak belirtilir) .
Patrick Allaert

2

DO: Sorgu ve / veya karşılaştırma yoluyla en çok eriştiğiniz alanları endeksleyin.

YAPMAYIN: Tablodaki her alanı daha hızlı yapacağını düşünerek dizinleyin.

Üzerinde herhangi bir istatistik yok, ama ben yardımcı olabilir eğer bir tablo içinde en fazla 4 dizinli alanları tutmaya çalışın. Veritabanlarımın normalleştirilmesi genellikle bu sayıları düşük tutmaya yardımcı olur, çünkü her şey sayısal tuşla aranabilir hale gelir (zaten daha hızlıdır). İndeksleme için tam metin alanlarından uzak durmaya çalışıyorum. Oldukça ağırlar.


2

Temel olarak, endeksler aramayı hızlandırır ancak yazmayı yavaşlatır ve yer kaplar. Bu değiş tokuş yapılır.

Tarafından katılmak, üzerinde arama yapmak / karşılaştırmak veya sipariş vermek için sıklıkla kullanılan herhangi bir alan, bir endeks adayıdır. Bunun gerçekten yapay olduğunu bilmek, ölçmek. Bununla birlikte, çok sayıda (> 1000'ler) kayıt ve az sayıda ek içeren yoğun birleştirilmiş tabloların yabancı anahtarları ödeyecektir.

Metin alanları için, sorgunuzu hızlandıracak ancak dizinlerdeki yükü hafifletecek alanın bir kısmına (örneğin, ilk 6 karakter) indeksleyebilirsiniz. Tam metin aramaları (üzerinde arama like %substring%), aşina olmadığım farklı teknikler gerektirir, bu yüzden orada size tavsiyede bulunamam.

Endekslerin yardımcı olmayacağı önemli bir durum: tarihin bir kısmında arama yaparken (/ katıl / sırala) tam tarih veya tarih-saat alanlarının dizinini kullanamazsınız. Tarihinde bir dizin date_createdsize benzer bir sorguda yardımcı olmaz select * from t where year(date_created) = 2011. Mysql'de tarihin bir bölümünde dizin oluşturamazsınız. ( Tarih alanında ' between' yerine ' ' year()kullandığınızda.)

Kılavuzdaki MYSQL hakkında daha fazla bilgi: http://dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html


1

DO: Kümelenmiş dizinin toplam boyutunu minimumda tutmaya çalışın. Kümelenmiş dizin girdileri diğer kümelenmemiş dizinlere dahil edilir ve buradan disk alanı israfı potansiyeli gelir.


1

Bir tabloyu, makalelerin görünüm sırasına göre sıralandığı (veya hiç yardımcı siparişin olmadığı) bir sözlük sözlüğü ve söz konusu sözlüğün kitap dizini olarak bir tablo dizini olarak düşünün.

Bir kitapta hızlıca bir şey bulmak için bir dizin kullanırsınız. Kitabın tamamını taramak yerine, yalnızca dizindeki anahtarı bulmanız gerekir (bir dizin genellikle bir şekilde sıralanır (kategoriye göre, bilimsel alana göre, tarihsel döneme vb.), Bu da taramanız gerekmeyeceği anlamına gelir dizinin tamamını) ve ardından sağ sayfaya atlayın.

Ancak bir kitaptan farklı olarak, tablo bir kez basılmaz ve sonra değiştirilemez. Her zaman güncellenir ve bu nedenle her dizin onunla güncellenmelidir. Bu elbette, sadece bir endeksin yararlılığı ile doğrulanabilecek bir alan ve zaman maliyetiyle gelir.

Bu nedenle, bu sütun sık arama sorgularında anahtar olarak kullanılıyorsa, bir sütun için bir dizin kullanın ve eğer değilse, bir sütun kullanmayın. Sıkça söylenen sözcük , genel olarak konuştukça aldığı kadar iyi bir niceliktir. Sonunda, hangilerinin sık olduğu hakkında iyi bir tahmin yapmanız ve ardından şüphe durumunda endeksli veya endekssiz performansı karşılaştırmanız gerekecektir.

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.