RDBMS'lerde “index” ne anlama geliyor? [kapalı]


21

Çoğu geliştiricinin yaptığı gibi dizinler kullanıyorum (çoğunlukla ... iyi! Dizin), ancak dizin kullanarak veritabanını optimize etmek için çok ince bir yöntem olduğuna eminim. Bir DBMS uygulamasına özgü olup olmadığından emin değilim.

Sorum şu: endeksin nasıl kullanılacağına dair iyi örnekler nelerdir (temel, açık durumlar hariç) ve bir tablo üzerinde bir dizin belirlediğinizde DBMS veritabanını nasıl optimize eder?


Bu soruyu daha da düşünerek, bu soru bu site için çok genel. Sorunun kapsamını uygun olabilecek şekilde değiştirirsek, aksi takdirde bu soru site için uygun değildir.
jcolebrand

Kütüphane metaforunu kullanarak dizinleri açıklamayı severim mysqlperformanceblog.com/2011/08/30/… Bakalım yardımcı olur mu ..
Jonathan

Yanıtlar:


11

Bir dizini "içindekiler tablosu" olarak düşünün ... bu, sıralı bir dosyadaki konum işaretçilerinin bir listesidir, yani ofsetler. Tabloda eşleşen milyonlarca kaydın bulunduğunu, tabloda eşleşen ölçütler için arama yapmak yerine, eşleşmeler için sıralı bir listeye başvurmanın çok daha hızlı olduğunu, ardından işaretçileri belirli eşleşen satırlara yığınladığını söyleyin. Mükemmel bir dizin örneği, tabloların birincil anahtar alanını, en çok da "id" alanını belirtir. Satır kimliği # 11234566 istiyorsanız, dizinden veri işaretçisini 11234566 konumu için veri kaynağını taramaktan çok daha hızlı isteyin.

İşte endekslemenin çok açık bir kullanımı:

CREATE TABLE activity_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
activity_type_id SMALLINT UNSIGNED NOT NULL,
datetime_created DATETIME
KEY(activity_type_id),
PRIMARY KEY(id)
);
CREATE TABLE activity_log_to_date_key (
activity_log_id INT UNSIGNED NOT NULL,
date_created_key  INT UNSIGNED NOT NULL REFERENCES dim_datetime(id),
UNIQUE KEY(activity_log_id),
KEY(date_created_key)
);
CREATE TABLE dim_datetime (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
date_hour DATETIME NOT NULL,
PRIMARY KEY(id),
KEY(date_hour)
);

İşleminiz, günlük kaydınızı oluşturabilir, ancak daha sonra aramak / sıralamak için, günlük tablonuzdan daha hızlı olan indekslenmiş bir tarih saatine referans oluşturur. Ardından log tablonuzu kendi ana anahtarında birleştirin. Bu konuyu genişletmeme ihtiyacın olursa haberim olsun. Umarım bu mantıklı gelir.

Örnek sorgu:

SELECT a.activity_log_id, al.activity_type_id, al.datetime_created
FROM activity_log_to_date_key a 
INNER JOIN dim_datetime d ON (d.id = a.date_created_key)
LEFT JOIN activity_log al ON (al.id = a.activity_log_id)
WHERE d.date_hour BETWEEN '2009-01-01 00:00:00' AND '2009-06-01 12:00:00';

teşekkürler, bu çok açık! Örneğinizde, "PRIMARY", RDMBS'nin "ofset" özelliğini kaydetme biçimini değiştirir mi, yoksa yalnızca benzersiz kısıtlamalar için mi kullanılır?
Thomas Joulin

9

Birçok insanın kaçırdığı görünen bir nokta, bir DBMS'nin bir sorguda tablo referansı başına yalnızca bir dizin kullanmasıdır (veya yalnızca) kullanmasıdır ve birden fazla dizin kullanabiliyorsa ve birden çok dizin kullanıyorsa, muhtemelen bir birleşik kullanmak daha hızlı olacaktır. eğer varsa indeks.

Örneğin, satırlar WHERE AnIntegerColumn = 42 AND AnOtherInt = 69için büyük bir tablo ararken , bu satırlara giden en hızlı yol, iki sütunda AnIntegerColumn ve AnOtherInt dizininde olur. Her biri için ayrı ayrı bir dizininiz varsa ancak birleştirilmiş bir dizininiz yoksa, DB bir veya diğer bir dizini arayacak ve sonuçları ikinci cümlede ayrı ayrı filtreleyecek veya her ikisini de tarayacak ve sonuçları daha sonra evlenecektir.

Kompozit endekslerle geliştirilebilecek bir diğer yaygın basit işlem WHERE SomeColumn = <SomeValue> ORDER BY SomeOtherColumn- eğer SomeColumn ve SomeOtherColumn üzerinde bir indeks varsa (doğru sırada), bazı durumlarda filtreleme ve sipariş işlemleri aynı anda yapılabilir.

Çok fazla endeks eklemek elbette kötü bir optimizasyon olabilir, çünkü endeksleri saklamak için kullanılan fazladan alan (ve DB'niz birçok yazma işlemi görürse bunları korumak için IO yükü), daha az optimal okuma sorgularından daha kötü bir problem olabilir , bu yüzden aşırı yapma.


2

David ve Randy bunu korudu. Sadece eklemek istedim komut büyük bir dizin oluşturma, hem de indeksleri gerekli olan düşündüren dışarı tasarruf alacak zaman bulmaktan büyük bir yardımcı olabilir. Sorgunuzu çalıştırmak için veritabanının attığı adımları görüntüler, böylece hangi bitlerin en uzun sürdüğünü bilirsiniz.EXPLAIN


Gaurav'in cevabına eklemek için, "EXPLAIN EXTENDED" kullanın, ardından sorgunuzun nasıl çevrildiğini görmek için hemen "SHOW WARNINGS" yazın.
randomx

1

Burada daha önce bahsetmediğim bir şey, birden fazla diske sahip olduğunuzda, muhtemelen dizininizi verinin bulunduğu yerden farklı bir diske koymak isteyeceğinizdir. Bu bazı işlemleri hızlandırabilir. Sanırım bu kendi başına bir soruyu hak ediyor.


Bu eskiden doğruydu, ancak bu günlerde söylüyoruz G / Ç alt sisteminizi ikinci kez tahmin etmeye çalışmaz. Bir depolama dizisinin yine de verilerinizi nereye yerleştireceğini bilmiyorsunuz.
Gaius

1
Eğer bir RAID5'I (veya benzeri) kurulum yoktu E :, F verilere :, vb dizinleri koymak eğer @gaius doğrusu demek
jcolebrand
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.