2011-07-17 33 views
40

Kullanıcılara ve GeoPhone tablolarına katılmak için CROSS UYGULAMASI kullanıyordum ve her şey hızlı çalıştı ancak şimdi Telefon sütununda NULL değerlere sahip Kullanıcılarım var. Çapraz uygulama, bu satırları son çıktıda atlar. Bu yüzden DIŞ UYGULAMAYA geçiş yaptım. Ancak, büyük ölçüde daha yavaş çalışır (çıktıdaki toplam satır sayısı sadece 1000 arttığında 15 kattan daha yavaş).CROSS APPLY vs DIŞ APPLY hız farkı

SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, GeoPhone.Country 
FROM dbo.Users CROSS APPLY 
       (SELECT TOP 1 Country 
       FROM dbo.GeoPhone 
       WHERE dbo.Users.Phone <= dbo.GeoPhone.[End]) GeoPhone 

Karşı:

SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, GeoPhone.Country 
FROM dbo.Users OUTER APPLY 
       (SELECT TOP 1 Country 
       FROM dbo.GeoPhone 
       WHERE dbo.Users.Phone <= dbo.GeoPhone.[End]) GeoPhone 

Nedenini anlamaya çalışıyorum. Gördüğüm gibi yürütme planı farklı. Ancak teorik olarak böyle bir yavaşlamaya neden olabilecek herhangi bir hesaplama göremiyorum.

Herhangi bir fikrin var mı?

MY SON ÇÖZÜM:

SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, GeoPhone.Country 
FROM dbo.Users CROSS APPLY 
       (SELECT TOP 1 Country 
       FROM dbo.GeoPhone 
       WHERE ISNULL(dbo.Users.Phone, 0) <= dbo.GeoPhone.[End]) GeoPhone 

Bu (zaten benim durum için "BİLİNMEYEN" dır) boş telefonlar için ilk aralıktan boş olmayan telefonlar ve ülke için gerçek Ülke atar. Bazı nedenlerden dolayı WHERE dbo.Users.Phone <= dbo.GeoPhone.[End] OR dbo.Users.Phone IS NULL aynı sonuçları veriyor ancak oldukça yavaş.

Lütfen yorumunuzu bildirmekten çekinmeyin. ÇAPRAZ GEÇERLİ

cevap

57

Microsoft on APPLY nedenlerini sol taraftaki sorguda sonucu başına bir kez çalıştırmak için sağ taraftaki sorgu GEÇERLİ ... MSSQL özeldir. CROSS sadece INNER JOIN gibi eşleşen satırları dikkate alır. OUTER kullanarak, tüm satırları sol taraftaki sorguda ele alır. Ekstra satırlar acıyor.

DIŞ UYGULAMA'yı kullanmak yerine NULL'ları açıkça kabul etmek için sağ taraftaki sorgunuzu yeniden formüle etmenizi öneririz.

+2

size Magicianeer teşekkürler dbo.Users.Phone üzerinde bir dizin olduğundan emin olun, ben sağ taraftaki sorgu yeniden formüle etmeye çalıştı ve bulunan mesajınıza sonra hızlı çözüm . İlk mesaja ekledim. – Denis

9

Bu deneyebilirsiniz:

SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, GeoPhone.Country 
FROM dbo.Users CROSS APPLY 
       (SELECT TOP 1 Country 
       FROM dbo.GeoPhone 
       WHERE dbo.Users.Phone <= dbo.GeoPhone.[End]) GeoPhone 
UNION ALL 
SELECT TOP (10000) dbo.Users.Login, dbo.Users.Phone, NULL AS Country 
FROM dbo.Users 
WHERE dbo.Users.Phone IS NULL 

+0

Bu hızlı çalışıyor! Ama biraz daha hızlı bir çözüm buldum. Onu soruma ekledim. – Denis

İlgili konular