@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 a
yalnız ve sorgu iki sütunu birleştiren daha iyi kitlesel olduğunu. Bazı veritabanları tablo üzerinde a
ve 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.