2013-09-24 204 views
1

我有以下表結構:替代嵌套的SELECT語句

enter image description here

目前正在過濾的用戶是通過非常複雜的嵌套的SQL查詢(此外,它通過LINQ的是自動生成的)來實現。我看起來大概是這樣的:

SELECT FROM (SELECT FROM (SELECT FROM (infinity here...)))) 

有沒有簡化過濾過程的好方法?

請注意,有不同的特徵類型。下面是子查詢條件的樣本:

... WHERE cv.Text like '%aaa%' AND c.Id = 5 
... WHERE cv.ImageId IS NOT NULL AND c.Id = 10 
... WHERE cv.Number > 5 AND c.Id = 33 

等等

會明白任何幫助和想法(DB改變結構,改變工藝,等...),謝謝!

+1

如果它是由LINQ生成的,那麼爲什麼你會關心它是否顯得複雜?數據庫應該是它看起來是3NF的。您可能在ImageId和AllowedValueId上缺少FK。 – Paparazzi

+0

有FKs,我只是不需要將它們添加到數據庫圖來簡化視圖。其實我並不是100%信任LINQ,我認爲自動生成的SQL腳本(以後稱爲'exec')遠不是最佳性能。也許某些DB視圖或存儲過程會提供更好的結果。 –

+1

你的LINQ查詢在哪裏? – christiandev

回答

1

正如你描述它,您的查詢應該是這樣的

select u.id 
from Users as u 
where 
    exists (
     select * 
     from CharacteristicValues as cv 
     where cv.Text like '%aaa%' and cv.CharacteristicId = 5 and u.Id = cv.UserId 
    ) and 
    exists (
     select * 
     from CharacteristicValues as cv 
     where cv.ImageId is not null and cv.CharacteristicId = 10 and u.Id = cv.UserId 
    ) and 
    exists (
     select * 
     from CharacteristicValues as cv 
     where cv.Number > 5 and cv.CharacteristicId = 33 and u.Id = cv.UserId 
    ) 

甚至

select distinct cv.UserId 
    from CharacteristicValues as cv 
    where cv.Text like '%aaa%' and cv.CharacteristicId = 5 

    union 

    select distinct cv.UserId 
    from CharacteristicValues as cv 
    where cv.ImageId is not null and cv.CharacteristicId = 10 

    union 

    select distinct cv.UserId 
    from CharacteristicValues as cv 
    where cv.Number > 5 and cv.CharacteristicId = 33 
+0

在這種方法中也有很多'SELECT'語句。我正在考慮'類似樞軸'的方法。用列生成一些tmp表/視圖:UserId,Characteristic1Value,Characteristic2Value,Ch-c3Val,C4V,... CnV。如果我有這樣的表,那麼我將能夠使用如下條件運行單個'SELECT':WHERE C1V = 5和C7V不是NULL並且C37> 3和C88 LIKE'%Bob%'。 我認爲使用'pivot'SQL關鍵字或OLAP方法。但另一個問題是可能會有2-5K +特性和100K +用戶。 –

+0

我正在分析TFS DB結構。它與我的DB有相似的結構。這裏是相關性:WorkItem <-> User;字段<->特徵; FieldValue <->特徵值。 TFS支持添加新字段,並且它有自己的WIQL(工作項查詢語言)。我對該查詢進行了剖析,發現它是針對包含具有所有字段的列的聚合視圖運行的。但不太可能這種方法不適用於我的情況。普通的MSSQL表格只能有1024列。當然,我可以使用寬表......但是解決方案會稍微複雜一些。 –

1

SQL到LINQ將是一個貧窮的表演
如果要優化性能和可擴展性然後去TSQL

  1. 數據庫設計3nf
  2. 指標
    也不要過度,因爲他們在EXE開始減緩插入和更新
  3. 查詢設計
  4. 本地緩存

本地緩存
下載靜態或半靜態的FK表的索引並將它們保存在字典中。
然後在你的下拉菜單中使用Dictionary而不是另一個對SQL的調用。
然後在查詢中,我發送FK ID,這樣select就減少了一次連接(它有所不同)。