Bölüm 9'a (Ayrıştırıcı ve Optimize Edici) göre, Sasha Pachev'in MySQL İç Kısmını Anlama Kitabı
İşte bir sorgu aşağıdaki görevler olarak değerlendirme dökümü:
- Kayıtları tablolardan almak için hangi tuşların kullanılabileceğini belirleyin ve her tablo için en iyisini seçin.
- Her tablo için, bir tablo taramasının bir anahtardaki okumadan daha iyi olup olmadığına karar verin. Anahtar değeriyle eşleşen çok fazla kayıt varsa, anahtarın avantajları azalır ve tablo taraması hızlanır.
- Sorguda birden fazla tablo bulunduğunda tabloların birleştirilme sırasını belirleyin.
- Ölü kodu ortadan kaldırmak için WHERE yan tümcelerini yeniden yazın, gereksiz hesaplamaları azaltın ve tuşları kullanma yolunu açmak için mümkün olan her yerde kısıtlamaları değiştirin.
- Kullanılmayan tabloları birleştirmeden kaldırın.
- Anahtarlar için kullanılıp kullanılamayacağını belirlemek
ORDER BY
ve GROUP BY
.
- Alt sorguları basitleştirmeyi deneyin ve sonuçlarının ne ölçüde önbelleğe alınabileceğini belirleyin.
- Görünümleri birleştir (görünüm referansını makro olarak genişlet)
Aynı sayfada şunu söylüyor:
MySQL optimizer terminolojisinde, her sorgu bir birleşim kümesidir. Terimi katılmak SQL komutları göre daha geniş buraya kullanılır. Yalnızca bir tablodaki sorgu, dejenere birleşimdir. Normalde bir tablodaki kayıtları bir birleştirme olarak okumayı düşünmese de, geleneksel birleşimlerle kullanılan aynı yapılar ve algoritmalar sorguyu tek bir tabloyla çözmek için mükemmel çalışır.
SONSÖZ
Mevcut anahtarlar, veri miktarı ve sorgunun ifadesi nedeniyle, MySQL Joins bazen kendi iyiliğimiz (veya bize geri dönmek) için şeyler yapabilir ve beklemediğimiz ve hızlı bir şekilde açıklayamadığımız sonuçlarla gelebilir.
Bu tuhaflık hakkında daha önce yazmıştım
çünkü MySQL Sorgu Optimize Edici, sorgunun değerlendirilmesi sırasında bazı anahtarları işten çıkarabilir.
@ Phil'in yorumu bu cevabı nasıl göndereceğimi görmeme yardımcı oldu (@ Phil'in yorumu için +1)
@ ypercube'un yorumu (bunun için +1 de) gönderimin kompakt bir sürümüdür, çünkü MySQL'in Sorgu Doktoru ilkeldir. Ne yazık ki, dış depolama motorlarıyla uğraştığından beri olmalı.
SONUÇ
Asıl sorunuza gelince, MySQL Sorgu Optimize Edici her sorgunun tamamlandığında performans metriklerini belirleyecektir
- satır sayma
- tuşları seçme
- aralıklı sonuç kümelerine masaj yapma
- Oh evet, asıl katılıyor
Muhtemelen sorguyu yeniden yazarak (yeniden düzenleyerek) yürütme sırasını zorlamanız gerekir.
İşte verdiğiniz ilk Sorgu
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
İlk olarak NEREDE değerlendirmek için yeniden yazmayı deneyin
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
Bu kesinlikle EXPLAIN planını değiştirecektir. Daha iyi veya daha kötü sonuçlar verebilir.
Bir keresinde StackOverflow'da bu tekniği uyguladığım bir soruya cevap verdim. EXPLAIN çok korkunçtu ama performans dinamitti. Yalnızca doğru indekslerin mevcut olması ve bir alt sorguda LIMIT kullanılması nedeniyle işe yaradı .
Hisse senedi fiyatlarında olduğu gibi, Sorgular söz konusu olduğunda ve bunları ifade etmeye çalışırken, kısıtlamalar uygulanır, sonuçlar değişebilir ve geçmiş performans gelecekteki sonuçların göstergesi değildir.