Sorguyu tamamen yeniden gözden geçirmelisiniz
WHERE yan tümcelerini daha erken ve JOIN'leri daha sonra gerçekleştirmeyi deneyin
Select Count(1) from DetailsTable dt
join (Select UserId,Id FROM MasterTable where
created between @date1 and @date2) mt on mt.Id = dt.MasterId
join (Select Id FROM UserTable WHERE Role is NULL) ut
on ut.Id = mt.UserId;
Bu yeniden düzenlenmiş sorguda bir EXPLAIN planı çalıştırsanız ve orijinalinizin daha kötü görünse bile, yine de deneyin. Dahili olarak oluşturulan geçici tablolar kartezyen birleşimler gerçekleştirir, ancak bu tablolarla çalışmak daha küçüktür.
Bu fikri bu YouTube videosundan aldım .
StackOverflow'da çok karmaşık bir soruda videodan ilkeleri denedim ve 200 puanlık bir ödül aldım.
@gbn, doğru dizinlere sahip olduğunuzdan emin olarak bahsetti. Bu durumda, lütfen oluşturulan sütunu MasterTable'da dizine ekleyin.
Bir şans ver !!!
GÜNCELLEME 2011-06-24 22:31 EDT
Bu sorguları çalıştırmalısınız:
SELECT COUNT(1) AllRoles FROM UserTable;
SELECT COUNT(1) NullRoles FROM UserTable WHERE Role is NULL;
NullRoles X 20 <AllRoles ise (diğer bir deyişle, NullRoles tablo satırlarının% 5'inden azsa), UserTable'daki Rolü benzersiz olmayan bir dizin oluşturmalısınız. Aksi takdirde, Sorgu Optimize Edici muhtemelen bir dizin kullanarak devre dışı bırakabileceğinden, UserTable'ın tam bir tablosu yeterli olacaktır.
GÜNCELLEME 2011-06-25 12:40 EDT
Bir MySQL DBA olduğum için, bir şeyler yapma yöntemim olumlu kötümserlik ve muhafazakar olmak yoluyla MySQL Sorgu Optimize Edici'ye güvenmemeyi gerektirir. Bu nedenle, bir sorguyu yeniden düzenlemeyi veya MySQL Sorgu Optimize Edici'nin gizli kötü alışkanlıklarının önüne geçmek için gerekli kaplama dizinleri oluşturmayı deneyeceğim. @ gbn yanıt daha SQL Server sorguları değerlendirme daha "akıl sağlamlığı" olabilir daha eksiksiz gibi görünüyor.