Büyük bir sorguyu birden çok küçük sorguyu ayırmak daha mı iyi?


13

İstenilen sonuçları üretmek için alt tablo deyimleriyle birlikte birkaç tabloyu birleştirmek için gerçekten büyük bir sorguya ihtiyaç duyan durumlar vardır.

Benim sorum, birden çok daha küçük sorgu kullanmayı düşünmeliyiz ve mantıksal işlemleri DB'yi birden fazla çağrıda sorgulayarak uygulama katmanına getirmeli miyiz, yoksa hepsini bir arada tutmak daha mı iyi?
Örneğin, aşağıdaki sorguyu düşünün:

SELECT *
FROM   `users`
WHERE  `user_id` IN (SELECT f2.`friend_user_id`
                     FROM   `friends` AS f1
                            INNER JOIN `friends` AS f2
                              ON f1.`friend_user_id` = f2.`user_id`
                     WHERE  f2.`is_page` = 0
                            AND f1.`user_id` = "%1$d"
                            AND f2.`friend_user_id` != "%1$d"
                            AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
                                                            FROM   `friends`
                                                            WHERE  `user_id` = "%1$d"))
       AND `user_id` NOT IN (SELECT `user_id`
                             FROM   `friend_requests`
                             WHERE  `friend_user_id` = "%1$d")
       AND `user_image` IS NOT NULL
ORDER  BY RAND() 
LIMIT %2$d

Bunu yapmanın en iyi yolu nedir?

Yanıtlar:


14

Burada datagod ile büyük ve karmaşık sorgular üzerinde anlaşmayacağım. Bunları sadece düzensiz olduklarında sorun olarak görüyorum. Performans açısından, bunlar neredeyse her zaman daha iyidir, çünkü planlamacının bilgi alma konusunda daha fazla özgürlüğü vardır. Ancak, büyük sorguların sürdürülebilirlik göz önünde bulundurularak yazılması gerekir. Genel olarak, basit, iyi yapılandırılmış SQL, 200'den fazla satır için tek bir sorgu devam ederken bile hata ayıklaması kolay buldum. Bunun nedeni, genellikle ne tür bir sorunla uğraştığınız konusunda oldukça iyi bir fikriniz olmasıdır, bu nedenle sorguda kontrol etmeniz gereken birkaç alan vardır.

Bakım sorunları, IME, SQL yapısı bozulduğunda gelir. Alt seçimlerdeki uzun, karmaşık sorgular satır içi görünümlerde olduğu gibi okunabilirliği ve sorun gidermeyi bozar ve uzun sorgularda bunların her ikisinden de kaçınılmalıdır. Bunun yerine, mümkünse VIEW'ları kullanın (MySQL üzerindeyseniz, görünümlerin pek iyi performans göstermediğini, ancak diğer db'lerde çalıştığını unutmayın) ve bunların çalışmadığı yerlerde ortak tablo ifadeleri kullanın (MySQL bunları desteklemez) btw).

Uzun karmaşık sorgular, nerede yan tümcelerinizi basit tuttuğunuz ve alt seçimler yerine birleştirmelerle yapabildiğiniz kadar çok yaptığınız bir sürdürülebilirlik ve performans durumundan oldukça iyi çalışır. Amaç, "kayıtlar görünmüyor" sorgusunda kontrol etmek için size çok belirli birkaç yer vermesini sağlamaktır (bir katılma işlemine bırakılıyor mu veya nerede bir maddede filtreleniyor mu?) Ve böylece bakım ekibi aslında bir şeyleri koruyabilir.

Ölçeklenebilirlik konusunda, planlayıcının esnekliği arttıkça, bunun da iyi bir şey olduğunu unutmayın.

Düzenleme: Bu MySQL olduğunu, bu yüzden görüşlerini iyi gerçekleştirmek olası değildir ve CTE's söz konusu değildir. Ayrıca verilen örnek özellikle uzun veya karmaşık değildir, bu yüzden sorun değildir.


Not: Oluşturulan sorgu planları optimal değildi yeterince uzun ve karmaşık sorguları (MySQL değil, ama yine de ...) oldu. Bu durumlarda, son derece karmaşık bir sorguyu daha az karmaşık iki sorguya bölen daha hızlı sonuçlar elde edebilirsiniz. Bununla birlikte, nadirdir ve genellikle karmaşık sorguyu yazacağım ve sorguyu daha önce küçük parçalara bölmek yerine bir sorun olup olmadığını öğreneceğim.
RDFozz

8

Bu büyük ve karmaşık sorguları desteklemek / temizlemek zorunda olan biri olarak, bunları anlaşılması kolay birkaç küçük parçaya ayırmanın çok daha iyi olduğunu söyleyebilirim. O değil mutlaka daha iyi bir görüş performans açısından, ancak SQL iyi sorgu planı ile gelip şansını artırır az altındadır.

Sizi takip eden insanlarda hayatı kolaylaştırın ve onlar sizin hakkınızda iyi şeyler söyleyeceklerdir. Onları zorlayın ve sizi lanetleyecekler.


2
bir dizi basit sorgunun dezavantajı, durumun bunlar arasında önemli ölçüde değişerek uygulamanın genel hata ayıklamasını daha karmaşık hale getirmesidir. Yani, büyük SQL sorgularında genellikle ağaç olarak hata ayıklayabilirsiniz, ancak uygulama kodu, deyimlerdeki durumun nasıl değiştiğini kontrol ederek ifade hata ayıklama deyimi alır. Gerçek konular, alt seçimlerin ve satır içi görünümlerin de kendi ağaçları olduğu gerçeği ile ilgilidir .....
Chris Travers

Benim durumumda DB ve kodu yönetmek zorunda olan tek kişi benim. Ve çoğunlukla sorum performans noktası sorgusu ile ilgili idi.
Hamed Momeni

Büyük toplu işlemlerimi yazma şeklimize bir göz atmanız gerekecek. Basit sorgulara ayırın, okunması çok kolay. Önyargılıyım çünkü toparlamaya çalıştığım sorgular rutin olarak 1000 satırdan uzun.
datagod

5

2 anahtar kelimemdeki 2 sentim sorgu performansı ve ölçeklenebilirliği:

Sorgu Performansı: SQL Server paralelliği zaten çok iş parçacıklı aramalara sorguları parçalamak için çok iyi bir iş yapıyor, bu yüzden SQL Server için yaparak ne kadar bir sorgu performans iyileştirmesi göreceğinizden emin değilim. Bununla birlikte, yürüttüğünüzde ne kadar paralellik elde edeceğinizi görmek ve sonuçları her iki şekilde karşılaştırmak için yürütme planına bakmanız gerekecektir. Aynı veya daha iyi performansı elde etmek için bir sorgu ipucu kullanmak zorunda kalırsanız, o zaman IMO buna değmez, çünkü sorgu ipucu daha sonra uygun olmayabilir.

Ölçeklenebilirlik: Verigodunun belirttiği gibi sorguları okumak daha kolay olabilir ve ayrı sorgulara ayırmak, yeni sorgularınızı başka alanlarda da kullanabiliyorsanız mantıklıdır, ancak başka aramalar için de kullanmayacaksanız, 1 görev için yönetmek daha da fazla depolanmış proc olacak ve IMO ölçeklenebilirliğe katkıda bulunmayacaktı.


2
RE: "SQL Server" referanslar OP herhangi bir RDBMS belirtmemiş olmasına rağmen ben arka keneler MySQL üzerinde olduğundan şüpheli veLIMIT
Martin Smith

@MartinSmith Doğru şüphelisiniz. MySQL.
Hamed Momeni

2

Bazı zamanlarda, büyük / karmaşık sorguyu küçük sorgulara bölmekten başka seçenek yoktur. Bunu belirlemenin en iyi yolu EXPLAIN, SELECTifadeyle ifadeyi kullanmak olacaktır . Db'nizin verilerinizi getirmek için yapacağı iz / tarama sayısı, EXPLAINsorgunuz tarafından döndürülen "satır" değerlerinin ürünüdür . Bizim durumumuzda, 10 tabloya katılan bir sorgu vardı. Özellikle kayıt için, DB'mizi bloke eden ve DB sunucumuzun CPU kullanımını% 300'ün üzerine çıkaran iz 409M'dir. Sorguları çok daha hızlı bölerek aynı bilgiyi elde edebildik.

Kısacası, bazı durumlarda karmaşık / büyük bir sorguyu bölmek mantıklıdır, ancak diğerlerinde birçok performans veya sürdürülebilirlik sorununa yol açabilir ve bu duruma göre ele alınmalı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.