Ölçeklenebilirlik düşünüldüğünde neden birleştirmeler kötü?


94

Birleştirmeler neden kötü veya 'yavaş'? Bunu bir kereden fazla duyduğumu biliyorum. Bu alıntıyı buldum

Sorun, özellikle çok büyük veri kümelerinde birleştirmelerin nispeten yavaş olması ve yavaşlarsa web sitenizin yavaş olmasıdır. Tüm bu ayrı bilgi parçalarını diskten alıp yeniden bir araya getirmek uzun zaman alır.

kaynak

Her zaman özellikle PK ararken hızlı olduklarını düşünmüşümdür. Neden 'yavaşlar'?

sql  join 

Yanıtlar:


100

Ölçeklenebilirlik, iş birimi başına kaynak kullanımını en aza indirmek için önceden hesaplama (önbelleğe alma), yayma veya tekrarlanan işi temel ihtiyaçlara indirgeme ile ilgilidir. İyi ölçeklendirmek için, hacim olarak gerek duymadığınız hiçbir şeyi yapmazsınız ve gerçekte yaptığınız şeylerin mümkün olduğunca verimli bir şekilde yapıldığından emin olursunuz.

Bu bağlamda, elbette iki ayrı veri kaynağını birleştirmek nispeten yavaştır, en azından onlara katılmamakla karşılaştırıldığında, çünkü kullanıcının istediği noktada canlı olarak yapmanız gereken bir iştir.

Ancak, alternatifin artık iki ayrı veri parçasına sahip olmadığını unutmayın; iki farklı veri noktasını aynı kayda koymanız gerekir. Bir yerde sonuç olmadan iki farklı veri parçasını birleştiremezsiniz, bu yüzden ödünleşmeyi anladığınızdan emin olun.

İyi haber, modern ilişkisel veritabanları birleştirme konusunda iyidir . İyi kullanılan bir veritabanı ile birleşimleri gerçekten yavaş düşünmemelisiniz. Ham birleşimler alıp çok daha hızlı hale getirmenin bir dizi ölçeklenebilirlik dostu yolu vardır :

  • Doğal bir anahtar yerine bir vekil anahtar (otomatik sayı / kimlik sütunu) üzerine katılın. Bu, birleştirme işlemi sırasında daha küçük (ve dolayısıyla daha hızlı) karşılaştırmalar anlamına gelir
  • Dizinler
  • Materyalleştirilmiş / dizine alınmış görünümler (bunu önceden hesaplanmış bir birleştirme veya yönetilen normalizasyondan çıkarma olarak düşünün )
  • Hesaplanan sütunlar. Bunu, bir birleşimin anahtar sütunlarına hash işlemi uygulamak veya başka bir şekilde önceden hesaplamak için kullanabilirsiniz, böylece bir birleştirme için karmaşık bir karşılaştırma olan şey artık çok daha küçük ve potansiyel olarak önceden dizine eklenmiştir.
  • Tablo bölümleri (yükü birden fazla diske yayarak veya bir tablo taraması olabilecekleri bir bölüm taramasına sınırlayarak büyük veri kümelerine yardımcı olur)
  • OLAP (belirli türden sorguların / birleştirmelerin sonuçlarını önceden hesaplar. Tam olarak doğru değil, ancak bunu genel denormalizasyon olarak düşünebilirsiniz )
  • Birden çok sunucunun aynı veritabanı için okuma sorgularını yanıtlamasına izin veren ve böylece iş yükünüzü birkaç sunucu arasında ölçeklendiren Replikasyon, Kullanılabilirlik Grupları, Günlük sevkiyatı veya diğer mekanizmalar.
  • Karmaşık birleştirmeler gerektiren sorguların yeniden çalıştırılmasını önlemek için Redis gibi bir önbellek katmanının kullanılması.

İlişkisel veritabanlarının var olmasının ana nedeninin, verimli bir şekilde katılmanıza izin vermek olduğunu söyleyecek kadar ileri gideceğim * . Kesinlikle sadece yapılandırılmış verileri depolamak değildir (bunu csv veya xml gibi düz dosya yapılarıyla yapabilirsiniz). Listelediğim seçeneklerden birkaçı, birleştirme işleminizi tamamen önceden oluşturmanıza bile izin verecek, böylece sonuçlar, sorguyu göndermeden önce zaten yapılmış - tıpkı verileri normalleştirmişsiniz gibi (kuşkusuz daha yavaş yazma işlemleri pahasına).

Yavaş bir katılımınız varsa, muhtemelen veritabanınızı doğru kullanmıyorsunuzdur.

Normalleştirme, ancak bu diğer teknikler başarısız olduktan sonra yapılmalıdır. Ve "başarısızlığı" gerçekten yargılamanın tek yolu, anlamlı performans hedefleri belirlemek ve bu hedeflere göre ölçüm yapmaktır. Ölçmediyseniz, normalleşmeyi düşünmek için bile çok erken.

* Yani, yalnızca tablo koleksiyonlarından farklı varlıklar olarak var olur. Gerçek bir rdbms için ek bir neden, güvenli eşzamanlı erişimdir.


14
Dizinler muhtemelen listenin başında olmalıdır. Pek çok ( öksürük ) geliştirici, küçük bir veri seti üzerinde test ederken bunları unutuyor ve ardından üretimde veritabanını dizlerinin üstüne getiriyor. Sadece dizinler ekleyerek 100.000 kat daha hızlı çalışan sorgular gördüm. Ve bu, en soldaki önek eşleşmesi için en iyi karışımı belirlemek için derinlemesine veri analizi yapmadan bile keyfi dizinler.
Duncan

Sanırım doğru bir sıraya sahibim - sadece çoğu geliştirici zaten ilk öğeyi yapıyor ve bu nedenle, değişiklik yapmaları gereken ilk öğe dizinler.
Joel Coehoorn

Üçüncü öğenizde "Materyalleştirilmiş / indekslenmiş görünümler" den bahsediyorsunuz. Normal SQL görünümlerinden mi yoksa başka bir şeyden mi bahsediyorsunuz?
slolife

@slolife normal sql görünümleri, görünüme başvuran bir sorgu kullandığınızda anında arka planda fazladan bir sorgu çalıştırmaya benzer. Ancak sql sunucusuna bazı görünümleri "somutlaştırmasını" da söyleyebilirsiniz. Bunu yaptığınızda, sql sunucusu, tıpkı normal bir tabloda olduğu gibi, görünüm verilerinin fazladan bir kopyasını saklayacaktır, böylece bir sorgudaki görünüme başvurduğunuzda artık bu sorguyu arka planda çalıştırmak zorunda kalmayacaktır çünkü veriler zaten oradadır. . Performansı ayarlamanıza daha fazla yardımcı olması için görünüme kaynak tablodan farklı dizinler de koyabilirsiniz.
Joel Coehoorn

Teşekkürler Joel. Buna bakmam gerekecek.
slolife

29

Birleştirmeler, normalleştirme yoluyla bunlardan kaçınmaktan daha yavaş olabilir, ancak doğru kullanılırlarsa (uygun dizinlerle sütunlarda birleştirme vb.) , Doğaları gereği yavaş değildirler .

Normalleştirme, iyi tasarlanmış veritabanı şemanız performans sorunları sergiliyorsa dikkate alabileceğiniz birçok optimizasyon tekniğinden biridir.


2
... indekslerinizin nasıl göründüğüne bakılmaksızın, çok sayıda birleştirme ile performans sorunları olan MySQL dışında. Ya da en azından geçmişte oldu.
Powerlord

2
Belirli bir DBMS (ve belki de sürüm) ile ilgili bilinen sorunlar varsa, bu tavsiye mantıklı olabilir, ancak genel bir tavsiye olarak, ilişkisel bir veritabanı kullanıyorsanız oldukça yanıltıcıdır. İlişkisel olmayan depolama mekanizmalarının daha popüler hale geldiği söylenen, Amazon'un SimpleDB ve CouchDB ( couchdb.apache.org ) örnekleridir. İlişkisel modeli geride bırakarak daha iyi hizmet alıyorsanız, muhtemelen arkada da optimize edilmiş ürünleri bırakıp başka araçlar aramalısınız.
Tendayi Mawushe

13

makale, birleşim yokluğuna kıyasla yavaş olduklarını söylüyor. bu, normalsizleştirme ile elde edilebilir. dolayısıyla hız ve normalleşme arasında bir değiş tokuş var. erken optimizasyonu da unutmayın :)


bu zor bir kural olmasa bile, bir tabloya katılırsanız, mysql bu birleştirmeyi gerçekleştirmek için bir indeks kullanabilir - bu indeks birleştirme birçok satırı ve tablolardaki herhangi bir where cümlesi için başka bir indeksi azaltabilir. Eğer katılmazsanız, mysql, nerede cümlenizin oluşturulduğuna bakılmaksızın, genellikle yalnızca bir indeks (en verimli olanı olmayabilir) kullanır.
leeeroy

12

Her şeyden önce, ilişkisel bir veritabanının varoluş nedeni (var olma nedeni) varlıklar arasındaki ilişkileri modelleyebilmektir. Birleşmeler, basitçe bu ilişkileri aştığımız mekanizmalardır. Kesinlikle nominal bir maliyetle gelirler, ancak birleştirme olmadan ilişkisel bir veritabanına sahip olmak için gerçekten bir neden yoktur.

Akademik dünyada, çeşitli normal formlar (1., 2., 3., Boyce-Codd, vb.) Gibi şeyleri öğreniriz ve farklı anahtar türleri (birincil, yabancı, alternatif, benzersiz vb.) Ve nasıl bunlar bir veritabanı tasarlamak için birbirine uyar. Ve hem yapıyı hem de verileri (DDL ve DML) değiştirmenin yanı sıra SQL'in temellerini öğreniyoruz.

Kurumsal dünyada, akademik yapıların birçoğu inanmaya yönlendirildiğimizden önemli ölçüde daha az uygulanabilir hale geldi. Mükemmel bir örnek, birincil anahtar kavramıdır. Akademik olarak tablodaki bir satırı benzersiz bir şekilde tanımlayan özniteliktir (veya öznitelikler koleksiyonudur). Bu nedenle birçok problem alanında, uygun akademik birincil anahtar 3 veya 4 özelliğin birleşimidir. Bununla birlikte, modern kurumsal dünyadaki hemen hemen herkes, tablonun birincil anahtarı olarak otomatik oluşturulan, sıralı bir tamsayıyı kullanır. Neden? İki sebep. Birincisi, FK'leri her yere taşırken modeli çok daha temiz hale getirmesidir. İkincisi ve bu sorunun en önemli yanı, birleştirmeler yoluyla veri almanın tek bir tamsayı üzerinde 4 varchar sütununda olduğundan daha hızlı ve daha verimli olmasıdır (daha önce birkaç kişi tarafından bahsedildiği gibi).

Şimdi, gerçek dünya veritabanlarının iki belirli alt türüne biraz daha derine bakalım. İlk tür, işlemsel bir veritabanıdır. Bu, modern siteleri yönlendiren birçok e-ticaret veya içerik yönetimi uygulamasının temelidir. Bir işlem DB'si ile, "işlem hacmi" doğrultusunda büyük ölçüde optimizasyon yaparsınız. Çoğu ticaret veya içerik uygulaması, sorgu performansını (belirli tablolardan) ekleme performansı (diğer tablolarda) ile dengelemek zorundadır, ancak her uygulamanın çözülmesi gereken kendine özgü iş odaklı sorunları olacaktır.

İkinci tür gerçek dünya veritabanı bir raporlama veritabanıdır. Bunlar, neredeyse yalnızca iş verilerini toplamak ve anlamlı iş raporları oluşturmak için kullanılır. Tipik olarak, verilerin üretildiği işlem veritabanlarından farklı bir şekle sahiptirler ve toplu veri yükleme hızı (ETL'ler) ve büyük veya karmaşık veri kümeleriyle sorgu performansı için oldukça optimize edilmiştir.

Her durumda, geliştiricinin veya DBA'nın hem işlevselliği hem de performans eğrilerini dikkatlice dengelemesi gerekir ve denklemin her iki tarafında çok sayıda performans artırıcı hile vardır. Oracle'da, bir sorgunun nasıl ayrıştırıldığını ve yürütüldüğünü spesifik olarak görebilmeniz için "açıklama planı" adı verilen şeyi yapabilirsiniz. DB'nin doğru dizin kullanımını maksimize etmek istiyorsunuz. Gerçekten kötü bir hayır-hayır, sorgunun where cümlesine bir işlev koymaktır. Bunu her yaptığınızda, Oracle'ın söz konusu sütunda herhangi bir dizin kullanmayacağını garanti edersiniz ve muhtemelen açıklama planında tam veya kısmi bir tablo taraması görürsünüz. Bu, yavaş sonuçlanan bir sorgunun nasıl yazılabileceğinin yalnızca bir örneğidir ve birleştirmelerle hiçbir ilgisi yoktur.

Tablo taramalarından bahsederken, bunlar açıkça sorgu hızını tablonun boyutuyla orantılı olarak etkiler. 100 satırlık tam bir tablo taraması bile fark edilmez. Aynı sorguyu 100 milyon satırlık bir tabloda çalıştırın ve geri dönüş için önümüzdeki hafta tekrar gelmeniz gerekecek.

Bir dakikalığına normalizasyondan bahsedelim. Bu, aşırı strese girebilecek büyük ölçüde olumlu bir akademik konudur. Normalizasyondan bahsettiğimizde çoğu zaman, yinelenen verileri kendi tablosuna koyarak ve bir FK'yi taşıyarak ortadan kaldırmayı kastediyoruz. İnsanlar genellikle 2NF ve 3NF tarafından tanımlanan tüm bağımlılık olayını atlarlar. Yine de aşırı bir durumda, muazzam büyüklükte mükemmel bir BCNF veri tabanına sahip olmak kesinlikle mümkündür ve çok normalleştirildiği için ona karşı kod yazmak için tam bir canavar.

Öyleyse nerede dengeliyoruz? Tek bir en iyi cevap yok. Daha iyi yanıtların tümü, yapı bakımı kolaylığı, veri bakımı kolaylığı ve kod oluşturma / bakım kolaylığı arasında bir miktar uzlaşma olma eğilimindedir. Genel olarak, verilerin ne kadar az kopyalanması o kadar iyidir.

Öyleyse neden birleşimler bazen yavaş? Bazen kötü ilişkisel tasarım. Bazen etkisiz indeksleme. Bazen bu bir veri hacmi sorunudur. Bazen korkunç yazılmış bir sorudur.

Bu kadar uzun soluklu bir cevap için özür dilerim, ancak 4 maddelik bir cevabı takırdatmaktansa yorumlarımın etrafında daha etli bir bağlam sağlamaya mecbur hissettim.


10

Terabayt büyüklüğünde veritabanları olan kişiler hala birleşimleri kullanıyor, eğer onları performans açısından çalıştırabiliyorlarsa siz de yapabilirsiniz.

Bozulmamak için birçok neden var. Birincisi, seçili sorguların hızı, veritabanları ile ilgili tek ve hatta temel sorun değildir. Verilerin bütünlüğü birinci husustur. Eğer normalliği bozarsanız, ana veriler değiştikçe verileri normalden arındırılmış tutmak için teknikler koymanız gerekir. Öyleyse, client_Id'deki müşteri tablosuna katılmak yerine, tüm tablolarda müşteri adını depolamaya karar verdiğinizi varsayalım. Şimdi, istemcinin adı değiştiğinde (% 100 şansla bazı istemcilerin adlarının zamanla değişmesi), şimdi bu değişikliği yansıtmak için tüm alt kayıtları güncellemeniz gerekir. Bunu kademeli bir güncelleme yapacaksanız ve bir milyon çocuk kaydınız varsa, bunun ne kadar hızlı olacağını ve bu gerçekleşirken kaç kullanıcı kilitlenme sorunları ve gecikmeler yaşayacak? Dahası, normal olmayan çoğu insan, çünkü "

Denormalizasyon, doğru bir şekilde yapılacaksa, veritabanı performansı ve bütünlüğünün tam olarak anlaşılmasını gerektiren karmaşık bir süreçtir. Personel konusunda bu tür bir uzmanlığa sahip değilseniz normalleştirmeye çalışmayın.

Birkaç şey yaparsanız, katılımlar yeterince hızlıdır. İlk önce bir öneri anahtarı kullanın, int birleştirme neredeyse her zaman en hızlı birleşmedir. İkinci olarak her zaman yabancı anahtarı dizine ekleyin. Filtrelenecek daha küçük bir veri kümesi oluşturmak için türetilmiş tabloları veya birleştirme koşullarını kullanın. Çok karmaşık bir veritabanınız varsa, büyük veritabanlarını bölümlere ayırma ve yönetme deneyimi olan profesyonel bir veritabanı çalışanı işe alın. Birleştirme işlemlerinden kurtulmadan performansı artırmak için birçok teknik vardır.

Sadece sorgu yeteneğine ihtiyacınız varsa, o zaman evet, normal olmayan ve kullanıcı veri girişi yerine bir ETL aracı (hız için optimize edilmiş) aracılığıyla doldurulan bir veri ambarını tasarlayabilirsiniz.


8

Birleşmeler yavaşsa

  • veriler yanlış şekilde dizine alınmış
  • sonuçlar kötü bir şekilde filtrelendi
  • katılma sorgusu kötü yazılmış
  • veri kümeleri çok büyük ve karmaşık

Dolayısıyla, doğru, verileriniz ne kadar büyükse, bir sorgu için o kadar fazla işleme ihtiyacınız olacaktır, ancak yukarıdaki ilk üç seçeneği kontrol etmek ve üzerinde çalışmak genellikle harika sonuçlar verecektir.

Kaynağınız bir seçenek olarak denormalizasyon veriyor. Bu, yalnızca daha iyi alternatifleri tükettiğiniz sürece iyidir.


7

Her iki taraftan da büyük kayıt bölümlerinin taranması gerekiyorsa, birleştirmeler yavaş olabilir.

Bunun gibi:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id

Üzerinde bir dizin tanımlansa bile account_customer, ikincisindeki tüm kayıtların yine de taranması gerekir.

Sorgu listesi için bu, iyi optimize ediciler muhtemelen indeks erişim yolunu düşünmeyecekler, bunun yerine a HASH JOINveya a yapacaklar MERGE JOIN.

Bunun gibi bir sorgu için şunları unutmayın:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id
WHERE   customer_last_name = 'Stellphlug'

birleştirme büyük olasılıkla hızlı olacaktır: ilk olarak, customer_last_nametüm Stellphlug'ları filtrelemek için bir indeks kullanılacaktır (ki bunlar elbette çok sayıda değildir), ardından account_customerişlemlerini bulmak için her Stellphlug için bir indeks taraması yapılacaktır.

Bu kayıtların milyarlarca olabilir gerçeğine rağmen accountsve customerssadece birkaç irade aslında taranacak gerekir.


ama bundan kaçınmak zordur. Uygulamanızı, bu tür sorgular çok sık yürütülmeyecek şekilde tasarlayın.
Andrey

1
accounts(account_customer)Çoğu RDBMS'de bir dizin tanımlandıysa , customersveritabanının tam olarak hangi satırlarının taranması gerektiğini bulmak için bu dizini kullanır .
jemfinch

evet, ama yine de ucuz bir operasyon değil. Toplamı bir alanda saklayabilir ve her işlemde güncelleme yapabilirsiniz.
Andrey

@jemfinch: hayır, olmayacaklar. Bu, yalnızca müşterileri filtrelemek için tüm dizinin taranmasını ve ardından müşterinin dizinini iç içe geçmiş bir döngüde taramayı gerektirir. A HASH JOINçok daha hızlı olurdu, bu yüzden tüm büyük veritabanları haricinde kullanılacak MySQLolan şey bu, sadece customersiç içe bir döngüde liderlik yapacak (boyutu daha küçük olduğu için)
Quassnoi

4

Joins are fast.Birleştirmeler, uygun şekilde normalleştirilmiş bir veritabanı şemasıyla standart uygulama olarak düşünülmelidir. Birleştirmeler, farklı veri gruplarını anlamlı bir şekilde birleştirmenize olanak tanır. Birleşmeden korkmayın.

Uyarı, normalleştirme, birleştirme ve dizinlerin doğru kullanımını anlamanız gerektiğidir.

Tüm geliştirme projelerinin bir numaralı başarısızlığı son teslim tarihini karşıladığından erken optimizasyona dikkat edin. Projeyi tamamladıktan ve değiş tokuşları anladıktan sonra, gerekçelendirebilirseniz kuralları çiğneyebilirsiniz.

Veri kümesinin boyutu arttıkça birleştirme performansının doğrusal olmayan bir şekilde düştüğü doğrudur. Bu nedenle, tek tablo sorguları kadar iyi ölçeklenmez, ancak yine de ölçeklenir.

Bir kuşun kanatsız daha hızlı uçtuğu da doğrudur, ama sadece dümdüz aşağı.


3

Verileri birbirine "birleştirmek" için daha fazla dosyaya ve daha fazla dizine bakmaları gerektiğinden, birleştirme işlemleri fazladan işlem gerektirir. Ancak, "çok büyük veri kümeleri" tamamen görelidir. Large'nin tanımı nedir? JOIN'ler durumunda, bunun genel veri kümesine değil, büyük bir sonuç kümesine atıfta bulunduğunu düşünüyorum.

Çoğu veritabanı, birincil tablodan 5 kayıt seçen ve her kayıt için ilgili tablodan 5 kaydı birleştiren bir sorguyu çok hızlı bir şekilde işleyebilir (doğru dizinlerin yerinde olduğu varsayılarak). Bu tabloların her biri yüz milyonlarca, hatta milyarlarca kayıt içerebilir.

Sonuç kümeniz büyümeye başladığında işler yavaşlayacak. Aynı örneği kullanarak, birincil tablo 100 bin kayıtla sonuçlanırsa, bulunması gereken 500 bin "birleştirilmiş" kayıt olacaktır. Veritabanından bu kadar çok veriyi gecikmelerle çekerek.

JOIN'lerden kaçınmayın, sadece veri kümeleri "çok büyük" olduğunda optimize etmeniz / denormalize etmeniz gerekebileceğini bilin.


3

Ayrıca alıntı yaptığınız makaleden:

Milyarlarca kayıt, petabaytlarca veri, binlerce eşzamanlı kullanıcı ve günde milyonlarca sorgu içeren mega ölçekli web sitelerinin çoğu, bir parçalama şeması kullanıyor ve hatta bazıları, veri katmanını tasarlamak için en iyi strateji olarak denormalizasyonu savunuyor.

ve

Ve gerçekten büyük bir web sitesi değilseniz, muhtemelen bu karmaşıklık düzeyi için endişelenmenize gerek yoktur.

ve

Veritabanının tüm bu işi yapmasından daha fazla hataya meyillidir, ancak en yüksek son veritabanlarının bile kaldırabildiğinden daha fazla ölçeklendirme yapabilirsiniz.

Makale Ebay gibi mega siteleri tartışıyor. Bu kullanım düzeyinde, basit vanilya ilişkisel veritabanı yönetiminden başka bir şeyi düşünmeniz gerekecektir. Ancak işin "normal" seyrinde (binlerce kullanıcı ve milyonlarca kayıttan oluşan uygulamalar) daha pahalı, daha fazla hata yapmaya meyilli yaklaşımlar aşırıdır.


2

Birleştirmeler, ölçeklenebilirliğe zıt bir güç olarak kabul edilir çünkü bunlar genellikle darboğazdır ve kolayca dağıtılamaz veya paralelleştirilemezler.


Bunun doğru olduğundan emin değilim. Teradata'nın kesinlikle birleşimleri Amperler arasında dağıtabildiğini biliyorum. Açıkçası, belirli birleştirme türleri diğerlerine göre daha zor / zorlu olabilir.
Cade Roux

dizinler RDBMS'de mysql'den oracle'a kadar bölümlenebilir. Ölçeklenen AFAIK (dağıtılır ve paralelleştirilebilir).
mantıksızlık

2

Doğru endeksleri ve doğru yazılmış sorguları içeren uygun şekilde tasarlanmış tablolar her zaman yavaş değildir. Bunu nereden duydun:

Birleştirmeler neden kötü veya 'yavaş'

ne hakkında konuştukları hakkında hiçbir fikri yok !!! Çoğu birleştirme çok hızlı olacaktır. Bir seferde çok sayıda satırı birleştirmeniz gerekiyorsa, normal olmayan bir tabloyla karşılaştırıldığında bir darbe alabilirsiniz, ancak bu Düzgün tasarlanmış tablolara geri döner, ne zaman normalleştirip ne zaman yapılmayacağını bilin. yoğun bir raporlama sisteminde, verileri raporlar için normalleştirilmiş tablolara ayırın, hatta bir veri ambarı oluşturun. İşlemsel ağır bir sistemde tabloları normalleştirin.


1

Oluşturulan geçici verilerin miktarı, birleştirmelere bağlı olarak çok büyük olabilir.

Örneğin, iş yerindeki bir veritabanı, tüm alanların isteğe bağlı olduğu genel bir arama işlevine sahipti. Arama rutini, arama başlamadan önce her masada bir birleştirme yaptı. Bu başlangıçta iyi çalıştı. Ama şimdi ana masanın 10 milyondan fazla satırı olduğu için ... o kadar değil. Aramalar artık 30 dakika veya daha uzun sürüyor.

Saklı arama yordamını optimize etmekle görevlendirildim.

Yaptığım ilk şey, ana tablodaki alanlardan herhangi biri aranıyorsa, yalnızca bu alanlarda geçici bir tablo seçtim. SONRA, aramanın geri kalanını yapmadan önce tüm tabloları bu geçici tabloyla birleştirdim. Ana tablo alanlarından birinin artık 10 saniyeden kısa sürdüğü aramalar.

Ana tablo alanlarından hiçbiri aramaya başlamazsa, diğer tablolar için benzer optimizasyonlar yaparım. İşim bittiğinde, çoğu 10'un altında olan hiçbir arama 30 saniyeden uzun sürmez.

SQL sunucusunun CPU kullanımı da AŞAĞI gitti.


@BoltBait: Bir katılma gerçekleştirmeden önce her zaman satır sayısını azaltmaya çalışmanız gereken paket servis mesajı mı?
unutbu

Benim durumumda kesinlikle harikalar yarattı. Ancak, gerekli olana kadar bir sistemi optimize etmem.
BoltBait

normalde birleştirmelerde hiçbir geçici veri üretilmez (elbette seçiciliğe, kullanılabilir belleğe ve birleştirme tamponlarının boyutuna bağlı olarak), AFAIK; ancak geçici veriler tipik olarak sırayla oluşturulur ve bu tür işlemler için kullanılabilecek bir dizin yoksa ayrıdır.
mantıksızlık

1

Birleştirmeler (muhtemelen normalleştirilmiş bir tasarıma bağlı olarak), veri alımı için tek bir tablodan okumaya göre açık bir şekilde daha yavaş olabilirken, normal olmayan bir veritabanı veri oluşturma / güncelleme işlemleri için yavaş olabilir çünkü genel işlemin ayak izi minimum olmayacaktır.

Normalleştirilmiş bir veritabanında, bir veri parçası yalnızca tek bir yerde yaşar, bu nedenle bir güncelleme için ayak izi mümkün olduğunca minimum düzeyde olacaktır. Normalden arındırılmış bir veritabanında, birden çok satırdaki veya tablolardaki aynı sütunun güncellenmesi gerekebilir, bu da ayak izinin daha büyük olacağı ve kilit ve kilitlenme olasılığı artabileceği anlamına gelir.


1

Evet, normal olmayan bir tablodan satır seçmek (sorgunuz için uygun dizinler varsayarak), özellikle birleşimlerde etkin dizinler yoksa, birkaç tablonun birleştirilmesiyle oluşturulan satırları seçmekten daha hızlı olabilir.

Makalede alıntılanan örnekler - Flickr ve eBay - istisnai durumlardır, bu nedenle istisnai yanıtlara sahip (ve hak ediyor). Yazar, özellikle RI eksikliğine ve makaledeki veri çoğaltmanın kapsamına dikkat çekiyor.

Çoğu uygulama - yine IMO - RDBMS'ler tarafından sağlanan doğrulama ve azaltılmış tekrarlamadan yararlanır.


0

Dikkatsizce yapılırsa yavaş olabilirler. Örneğin, bir birleşimde 'seç *' yaparsanız, muhtemelen işleri geri almanız biraz zaman alacaktır. Bununla birlikte, her tablodan hangi sütunların döndürüleceğini dikkatlice seçerseniz ve uygun dizinler yerindeyken, sorun olmamalıdır.

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.