2013-09-24 161 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就减少了一次连接(它有所不同)。