SQL serbest bırakıldı: SQL sorgularınızı hızlandırmanın 17 yolu

Her platformdaki SQL geliştiricileri DO WHILE, aynı hataları tekrar tekrar tekrar etmelerine neden olan bir döngüde sıkışmış gibi görünüyorlar . Bunun nedeni, veritabanı alanının hala nispeten olgunlaşmamış olmasıdır. Elbette, satıcılar bazı adımlar atıyor, ancak daha büyük sorunlarla boğuşmaya devam ediyorlar. SQL Server, Oracle, DB2, Sybase, MySQL veya başka herhangi bir ilişkisel platformda kodlama yapıyor olsalar da, eşzamanlılık, kaynak yönetimi, alan yönetimi ve hız SQL geliştiricilerinin başına bela olur.

Sorunun bir kısmı, sihirli bir merminin olmaması ve neredeyse her en iyi uygulama için size en az bir istisna gösterebilirim. Tipik olarak, bir geliştirici kendi favori yöntemlerini bulur - ancak bunlar genellikle performans veya eşzamanlılık için herhangi bir yapı içermez - ve diğer seçenekleri keşfetme zahmetine girmez. Belki de bu eğitim eksikliğinin bir belirtisidir veya geliştiriciler, yanlış bir şey yaptıklarında farkına varamayacak kadar sürece çok yakındırlar. Sorgu yerel bir test verisi kümesi üzerinde iyi çalışıyor olabilir, ancak üretim sisteminde perişan bir şekilde başarısız oluyor.

SQL geliştiricilerinin yönetici olmasını beklemiyorum, ancak kodlarını yazarken üretim sorunlarını dikkate almaları gerekiyor. İlk geliştirme sırasında yapmazlarsa, DBA'lar yalnızca geri dönmelerini ve daha sonra yapmalarını sağlar - ve bu arada kullanıcılar zarar görür.

Bir veritabanını ayarlamanın hem sanat hem de bilim olduğunu söylememizin bir nedeni var. Bunun nedeni, yönetim kurulunda geçerli olan çok az sert ve hızlı kuralın var olmasıdır. Bir sistemde çözdüğünüz sorunlar bir diğerindeki sorunlar değildir ve bunun tersi de geçerlidir. Sorguları ayarlamak söz konusu olduğunda doğru cevap yoktur, ancak bu vazgeçmeniz gerektiği anlamına gelmez.

Bir kombinasyonda veya başka bir kombinasyonda sonuç vermesi gereken izleyebileceğiniz bazı iyi ilkeler vardır. Bunları, genellikle gözden kaçan veya fark edilmesi zor olan SQL'de yapılması ve yapılmaması gerekenler listesine ekledim. Bu teknikler, DBA'larınızın zihinleri hakkında size biraz daha fazla fikir vermenin yanı sıra, süreçleri üretim odaklı bir şekilde düşünmeye başlama yeteneği sağlamalıdır.

1. Bunun UPDATEyerine kullanmayınCASE

Bu sorun çok yaygındır ve tespit edilmesi zor olmasa da, çoğu geliştirici bunu gözden kaçırır çünkü kullanım UPDATEmantıklı görünen doğal bir akışa sahiptir.

Örneğin şu senaryoyu ele alalım: Geçici bir tabloya veri ekliyorsunuz ve başka bir değer varsa belirli bir değeri görüntülemesi gerekiyor. Belki Müşteri tablosundan çekiyorsunuz ve 100.000 $ 'dan fazla siparişi olan herkesin "Tercih Edilen" olarak etiketlenmesini istiyorsunuz. Bu nedenle, verileri tabloya eklersiniz ve UPDATE100.000 $ 'dan fazla siparişi olan herkes için CustomerRank sütununu "Tercih Edilen" olarak ayarlamak için bir ifade çalıştırırsınız . Sorun, UPDATEifadenin günlüğe kaydedilmesidir, bu da tabloya her yazma için iki kez yazması gerektiği anlamına gelir. Elbette bunun etrafından dolaşmanın yolu CASESQL sorgusunun kendisinde bir satır içi ifade kullanmaktır . Bu, sipariş miktarı koşulu için her satırı test eder ve tabloya yazılmadan önce "Tercih Edilen" etiketini ayarlar. Performans artışı şaşırtıcı olabilir.

2. Kodu körü körüne yeniden kullanmayın

Bu sorun da çok yaygındır. Başkasının kodunu kopyalamak çok kolaydır çünkü ihtiyacınız olan verileri çektiğini bilirsiniz. Sorun şu ki, sık sık ihtiyaç duyduğunuzdan çok daha fazla veri çekiyor ve geliştiriciler nadiren bu verileri kırpmakla uğraşıyorlar, bu yüzden büyük bir veri seti elde ediyorlar. Bu genellikle fazladan bir dış birleşim veya WHEREmaddede bir ekstra koşul şeklinde gelir . Yeniden kullanılan kodu tam ihtiyaçlarınıza göre ayarlarsanız, büyük performans kazanımları elde edebilirsiniz.

3. Yalnızca ihtiyacınız olan sayıda sütun çekin

Bu sorun 2. sayıya benzer, ancak sütunlara özgüdür. SELECT *Sütunları ayrı ayrı listelemek yerine tüm sorgularınızı kodlamak çok kolaydır . Yine sorun, ihtiyacınız olandan daha fazla veri çekmesidir. Bu hatayı onlarca kez gördüm. Bir geliştirici, SELECT *120 sütun ve milyonlarca satır içeren bir tabloya karşı bir sorgu yapar , ancak bunların yalnızca üç ila beşini kullanarak sonuçlanır. Bu noktada, ihtiyacınız olandan çok daha fazla veri işliyorsunuz, sorgunun geri dönmesi bir mucize. Yalnızca ihtiyacınız olandan daha fazla veri işlemiyorsunuz, aynı zamanda kaynakları diğer işlemlerden de alıyorsunuz.

4. Çift daldırma

İşte sahip olmam gerekenden daha fazla kez gördüğüm bir tane daha: Yüz milyonlarca satır içeren bir tablodan veri çekmek için bir saklı yordam yazılmıştır. Geliştiricinin, Kaliforniya'da yaşayan ve 40.000 $ 'dan fazla geliri olan müşterilere ihtiyacı var. Bu yüzden Kaliforniya'da yaşayan müşterileri sorgular ve sonuçları geçici bir tabloya koyar; daha sonra geliri 40.000 $ 'ın üzerinde olan müşterileri sorgular ve bu sonuçları başka bir geçici tabloya koyar. Son olarak, nihai ürünü elde etmek için her iki masaya katılır.

Benimle dalga mı geçiyorsun? Bu, tek bir sorguda yapılmalıdır; bunun yerine, süper geniş bir masayı iki kez daldırıyorsunuz. Moron olmayın: Büyük tabloları mümkün olduğunca yalnızca bir kez sorgulayın - prosedürlerinizin ne kadar iyi performans gösterdiğini göreceksiniz.

Biraz farklı bir senaryo, büyük bir tablonun bir alt kümesinin bir işlemdeki birkaç adım için gerekli olması ve bu da büyük tablonun her seferinde sorgulanmasına neden olmasıdır. Alt kümeyi sorgulayıp başka bir yerde devam ettirip ardından daha küçük veri kümenize sonraki adımları işaret ederek bundan kaçının.

6. Aşama öncesi verileri yapın

Bu benim en sevdiğim konulardan biri çünkü genellikle gözden kaçan eski bir teknik. Büyük tablolara benzer birleştirmeler yapacak bir raporunuz veya prosedürünüz (veya daha iyisi bir dizi) varsa, tabloları önceden birleştirerek ve devam ettirerek verileri önceden aşamalandırmanız sizin için faydalı olabilir. bir masaya. Artık raporlar önceden hazırlanmış bu tabloya karşı çalıştırılabilir ve büyük birleştirme işleminden kaçınabilir.

Bu tekniği her zaman kullanamazsınız, ancak yapabildiğiniz zaman, bunun sunucu kaynaklarından tasarruf etmenin mükemmel bir yolu olduğunu göreceksiniz.

Birçok geliştiricinin, sorgunun kendisine odaklanarak ve birleştirme koşullarını tekrar tekrar yazmak zorunda kalmaması için birleştirme çevresinde yalnızca bir görünüm oluşturarak bu birleştirme sorununu aştığını unutmayın. Ancak bu yaklaşımla ilgili sorun, sorgunun ihtiyaç duyan her rapor için hala çalıştırılmasıdır. Verileri önceden aşamalandırarak, birleştirme işlemini yalnızca bir kez çalıştırırsınız (örneğin, raporlardan 10 dakika önce) ve diğer herkes büyük katılımdan kaçınır. Bu tekniği ne kadar sevdiğimi size söyleyemem; Çoğu ortamda, her zaman katılan popüler masalar vardır, bu nedenle önceden hazırlanmamaları için hiçbir neden yoktur.

7. Toplu işlerde silin ve güncelleyin

İşte çokça gözden kaçan başka bir kolay teknik. Doğru yapmazsanız, büyük tablolardan büyük miktarda veriyi silmek veya güncellemek bir kabusa dönüşebilir. Sorun, bu ifadelerin her ikisinin de tek bir işlem olarak çalışmasıdır ve bunları öldürmeniz gerekirse veya çalışırken sisteme bir şey olursa, sistemin tüm işlemi geri alması gerekir. Bu çok uzun zaman alabilir. Bu işlemler, diğer işlemleri de süreleri boyunca engelleyerek, esasen sistemde darboğaz oluşturabilir.

Çözüm, daha küçük gruplar halinde silme veya güncelleme yapmaktır. Bu, sorununuzu birkaç şekilde çözer. Birincisi, işlem herhangi bir nedenle öldürülürse, yalnızca geri alınacak az sayıda satır vardır, bu nedenle veritabanı çok daha hızlı çevrimiçi döner. İkincisi, daha küçük gruplar diske bağlıyken diğerleri gizlice girip biraz iş yapabilir, böylece eşzamanlılık büyük ölçüde artar.

Bu satırlar boyunca birçok geliştirici, bu silme ve güncelleme işlemlerinin aynı gün tamamlanması gerektiğini kafalarına takmış durumda. Bu her zaman doğru değildir, özellikle de arşivliyorsanız. Bu işlemi ihtiyaç duyduğunuz kadar uzatabilirsiniz ve daha küçük gruplar bunu başarmanıza yardımcı olur. Bu yoğun işlemleri yapmak daha uzun sürebilirse, fazladan zaman harcayın ve sisteminizi çökertmeyin.

8. İmleç performansını artırmak için geçici tablolar kullanın

Umarım mümkünse imleçlerden uzak durmanın en iyisi olduğunu şimdiye kadar hepimiz biliyoruz. İmleçler yalnızca hız sorunlarından muzdarip olmakla kalmaz, bu kendi başına birçok işlemle ilgili bir sorun olabilir, aynı zamanda işleminizin diğer işlemleri gerekenden çok daha uzun süre engellemesine de neden olabilir. Bu, sisteminizdeki eşzamanlılığı büyük ölçüde azaltır.

Bununla birlikte, imleç kullanmaktan her zaman kaçınamazsınız ve bu zamanlar ortaya çıktığında, imleç işlemlerini geçici bir tabloya karşı yaparak imleç kaynaklı performans sorunlarından uzaklaşabilirsiniz. Örneğin, bir tablodan geçen ve bazı karşılaştırma sonuçlarına göre birkaç sütunu güncelleyen bir imleci ele alalım. Karşılaştırmayı canlı tabloyla yapmak yerine, bu verileri geçici bir tabloya koyabilir ve bunun yerine karşılaştırmayı yapabilirsiniz. O zaman UPDATEcanlı masaya karşı çok daha küçük olan ve kilitleri yalnızca kısa bir süre tutan tek bir ifadeniz var.

Veri değişikliklerinizi bunun gibi kırpmak eşzamanlılığı büyük ölçüde artırabilir. Neredeyse hiç imleç kullanmanıza gerek olmadığını söyleyerek bitireceğim. Neredeyse her zaman set tabanlı bir çözüm vardır; onu görmeyi öğrenmen gerek.

9. Görünümleri iç içe yerleştirmeyin

Görünümler uygun olabilir, ancak bunları kullanırken dikkatli olmanız gerekir. Görünümler, kullanıcılardan gelen büyük sorguları gizlemeye ve veri erişimini standartlaştırmaya yardımcı olabilirken, kendinizi görünümleri çağıran görünümleri çağıran görünümlere sahip olduğunuz bir durumda kolayca bulabilirsiniz. Buna iç içe görünümler denir ve özellikle iki şekilde ciddi performans sorunlarına neden olabilir:

  • İlk olarak, ihtiyaç duyduğunuzdan çok daha fazla veriye sahip olacaksınız.
  • İkinci olarak, sorgu iyileştirici pes edecek ve kötü bir sorgu planı döndürecektir.

Bir zamanlar yuva görüşlerini seven bir müşterim vardı. Müşterinin neredeyse her şey için kullandığı bir görüşü vardı çünkü iki önemli birleşimi vardı. Sorun, görünümün içinde 2MB belgeler bulunan bir sütun döndürmesiydi. Belgelerin bazıları daha da büyüktü. İstemci, çalıştırdığı hemen hemen her sorguda her bir satır için ağda en az 2 MB fazladan para aktarıyordu. Doğal olarak, sorgu performansı berbattı.

Ve sorguların hiçbiri bu sütunu gerçekten kullanmadı! Tabii ki sütun yedi görüş derinliğine gömüldü, bu yüzden onu bulmak bile zordu. Belge sütununu görünümden kaldırdığımda, en büyük sorgu süresi 2,5 saatten 10 dakikaya çıktı. Sonunda, birkaç gereksiz birleşim ve sütuna sahip olan iç içe geçmiş görünümleri çözdüğümde ve düz bir sorgu yazdığımda, aynı sorgunun süresi alt saniyelere düştü.