2017-03-15 77 views
5

Farz edelim, bu durumda bölgelerden istemciden gönderilen bir dize listesi var. Ve Uygunluk Bölgeleri adlı bir masa var. Bir name özelliğine sahip satırları aramak istiyorum ve bölge öğesi bölge üzerinde bulunmalıdır.SQL INNER JOIN vs Var Olduğu Durum Performans Değerlendirmesi

LINQ'ta bunu iki farklı şekilde yapabilirim. Aşağıda olduğu gibi iki farklı SQL Sorgusu üretirler. Sorum şu ki hangisini seçmeliyim? Hangi sorgu daha iyi performansa sahip?

List<string> regions = new List<string>() { "Canada", "EN 50530" }; 

      var cregions = from c in complianceRegions 
          from r in regions 
          where c.Name.Equals(r) 
          select c; 

      var cregions2 = from c in complianceRegions 
          where regions.Any(x => x == c.Name) 
          select c; 

oluşturulan SQL aşağıda gösterdi.

cregions

Ve istendiği gibi

--cregions2 
    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Description] AS [Description] 
    FROM [Administration].[ComplianceRegions] AS [Extent1] 
    WHERE EXISTS (SELECT 
     1 AS [C1] 
     FROM (SELECT 
      N'Canada' AS [C1] 
      FROM (SELECT 1 AS X) AS [SingleRowTable1] 
     UNION ALL 
      SELECT 
      N'EN 50530' AS [C1] 
      FROM (SELECT 1 AS X) AS [SingleRowTable2]) AS [UnionAll1] 
     WHERE [UnionAll1].[C1] = [Extent1].[Name] 
    ) 

cregions2 Eklendi Yürütme planı

 -- cregions 
    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Description] AS [Description] 
    FROM [Administration].[ComplianceRegions] AS [Extent1] 
    INNER JOIN (SELECT 
     N'Canada' AS [C1] 
     FROM (SELECT 1 AS X) AS [SingleRowTable1] 
    UNION ALL 
     SELECT 
     N'EN 50530' AS [C1] 
     FROM (SELECT 1 AS X) AS [SingleRowTable2]) AS [UnionAll1] ON [Extent1].[Name] = [UnionAll1].[C1] 

.

+2

* Hangi sorgu daha iyi performansa sahip? * Kendi testleriniz neler gösterdi? –

+0

ilginç bir bölüm, aynı sorguyu birkaç kez çalıştırdığımda, SQL sunucusu sorguyu önbelleğe alır ve yanlış performans verir. –

+0

Neden ilk sorgu 'Contains' ve ikinci' == 'kullanır? Amaçlanan karşılaştırma operatörü hangisidir? Şu anda elmaları portakallarla karşılaştırıyorsunuz. –

cevap

2

İki alternatif göz önüne alındığında, ikincisi muhtemelen daha iyidir, çünkü sütun adında işlev çağrısı yoktur. Bununla birlikte, ikisi aynı değildir. Birincisi kısmi bir eşleşme yapar ve ikincisi tam bir eşleşme yapar. Neyi niyet ettiğini yapan şeyi yapmalısın. Performans doğruluğa ikincildir.

Her ikisi de acı verici. CHARINDEX() çıktısını bir dizine dökmek mi? "Gereksiz" diyebilir miyiz?

select . . . 
from [Administration].[ComplianceRegions] AS [Extent1] 
where Extent1.Name in (N'Canada', N'EN 50530'); 

Bu, bu mantığın en basit ve en iyi performans versiyonudur: Sorgu basitçe olmamasının sebebi

Onlar farzetmek.

+0

, ancak bu sorgular otomatik olarak oluşturulur. Daha iyi LINQ sorgusunu seçmem gerekiyor. –

+0

@FoyzulKarim: hem sorguların hem de şemaların yürütme planlarını yapıştırmanız gerekecek, ilgili tabloların sayısı. Bunun için bu soruya cevap verilemez – TheGameiswar

+0

* neden sorgu basitçe değil ... * çünkü kısmi maç için? –

0

@JNK yanıtının karşılığı in this post.

bir boolean değer döndürmek için kullanılır EXISTS, döndürür

sadece test etmek için kullanılır EXISTS bambaşka bir tablo JOIN sanki yakında yaptığı gibi bir alt sorgu sonuçları döndürür ve kısa devreler. JOIN, bir sonuç kümesini, bir ilişkinin bulunduğu başka bir tablodaki ek alanlarla birleştirerek genişletmek için kullanılır.

Örneğinizde, sorgular siparien eşdeğerdir.

Sen ilişkili tabloda dupes (değerler tekrarlandığı takdirde yinelenen satırları neden olabilir JOIN) İstiyorsun var ilgili tablodan veri döndürecek gerekmez: Genel olarak

, kullanım sırasında MEVCUT varlığını denetle (SOL DIŞI BIRAKMA yerine kullanın ... BOŞ durumda) Doğru dizinlere sahipseniz, çoğu zaman EXISTS, JOIN ile aynı şekilde performans gösterecektir. İstisna, normalde EXISTS kullanmak için daha hızlı olduğu çok karmaşık alt sorgulardadır.

JOIN anahtarınız endekslenmemişse, EXISTS'i kullanmak daha hızlı olabilir, ancak özel durumunuzu test etmeniz gerekir. JOIN sözdizimi normalde okunması ve daha temiz olması daha kolaydır.

0

Bu sorgular eşittir. Ve ikisi de berbat, bunlardan hiçbirini seçmezdim. Sabit kodlanmış değerlere sahipler, böylece tekrar kullanılamazlar. Sql server autoparametrization ile başa çıkabilir miyim emin değilim, bu yüzden yürütme planı önbellek muhtemelen acı çeker. Doğru çözüm, tablo değerli parametreler kullanıyor, maalesef bildiğim kadarıyla linq sağlayıcılarında desteklenmiyorlar. Yani kendi başına sorgu yapmak zorunda kalacaksınız, sadece sonucu elde etmek için linq kullanabilirsiniz.

Ivan Stoev tarafından sağlanan çözümü deneyebilir, sağlayıcınızın ne ürettiğine bağlıdır. Linq2sql, uzun listeler için iyi ölçeklenmez, çünkü sahip olduğunuz listedeki birçok öğe kadar çok parametre üretir. En azından, listedeki öğelerin sayısı aynı olduğunda yürütme planını yeniden kullanabilir.