İşte kısa süre önce işte ortaya çıkan bir senaryo.
A, B, C olmak üzere üç tabloyu düşünün.
A'nın 3.000 satırı vardır; B'nin 300.000.000 satırı vardır; ve C'nin 2.000 satırı vardır.
Yabancı anahtarlar tanımlanmıştır: B (a_id), B (c_id).
Şuna benzeyen bir sorgunuz olduğunu varsayalım:
select a.id, c.id
from a
join b on b.a_id = a.id
join c on c.id = b.c_id
Deneyimlerime göre, MySQL bu durumda C -> B -> A'yı seçebilir. C, A'dan daha küçüktür ve B çok büyüktür ve hepsi eşittir.
Sorun MySQL'in (C.id ve B.c_id) ile (A.id ve B.a_id) arasındaki kesişim boyutunu hesaba katmamasıdır. B ve C arasındaki birleşim, B kadar çok satır döndürürse, bu çok zayıf bir seçimdir; A ile başlamak, B'yi A kadar çok satıra kadar filtrelemiş olsaydı, çok daha iyi bir seçim olurdu. straight_joinbu emri şu şekilde zorlamak için kullanılabilir:
select a.id, c.id
from a
straight_join b on b.a_id = a.id
join c on c.id = b.c_id
Şimdi adaha önce birleştirilmelib .
Genellikle birleştirmelerinizi, sonuç kümesindeki satır sayısını en aza indiren bir sırayla yapmak istersiniz. Bu nedenle, küçük bir masa ile başlamak ve ortaya çıkan birleşim de küçük olacak şekilde birleştirmek idealdir. Küçük bir masa ile başlayıp onu daha büyük bir masa ile birleştirmek, büyük masa kadar büyük olur.
Yine de istatistiklere bağlıdır. Veri dağılımı değişirse, hesaplama değişebilir. Ayrıca birleştirme mekanizmasının uygulama ayrıntılarına da bağlıdır.
MySQL için gördüğüm en kötü durumlar, gerekli straight_joinveya agresif dizin ipuçlarının tümü, ışık filtrelemeli katı bir sıralama düzeninde çok fazla veriyi sayfalandıran sorgulardır. MySQL, tüm filtreler için dizin kullanmayı şiddetle tercih eder ve sıralı birleştirmeler; Bu mantıklıdır çünkü çoğu insan tüm veritabanını sıralamaya çalışmaz, bunun yerine sorguya yanıt veren sınırlı bir satır alt kümesine sahiptir ve sınırlı bir alt kümeyi sıralamak, sıralı veya sıralı olup olmadığına bakılmaksızın tüm tabloyu filtrelemekten çok daha hızlıdır. değil. Bu durumda, dizine alınmış sütunun bulunduğu tablonun hemen sonrasına düz birleştirme koyarak sabit şeyleri sıralamak istedim.
straight_join.