有没有办法优化下面给出的查询

时间:2008-12-17 10:20:05

标签: sql-server

我有以下查询,我需要查询根据Someothertable中的过滤条件从SomeTable获取数据。如果SomeOtherTable Query中没有任何内容,则应该返回SomeTable中存在的所有数据

SQL SERVER 2005

SomeOtherTable没有任何索引或任何约束,所有字段都是char(50)

以下查询可以满足我的要求,但是当我有很多参数时会导致性能问题。

由于Client的一些要求,我们必须将所有Where子句数据保存在SomeOtherTable中。取决于子数据将与SomeTable中的一列相连接。

例如,查询可以是

SELECT
    *
FROM
    SomeTable
WHERE
    1=1 
AND
(
SomeTable.ID in (SELECT DISTINCT ID FROM SomeOtherTable  WHERE Name = 'ABC' and subid = 'EF')
OR
0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC' and subid = 'EF')
)

AND 
    (
    SomeTable.date =(SELECT date FROM SomeOtherTable  WHERE Name = 'ABC' and subid = 'Date')
    OR
    0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC' and subid = 'Date')
    )

EDIT ----------------------------------------------

我想我可能需要详细解释我的问题:

我们开发了一个ASP.net应用程序,用于调用参数化水晶报告,水晶报告的参数不会使用默认的水晶报告方法传递。

在ASP.net应用程序中,我们创建了用于将参数传递给Reports的向导,这些参数不是由水晶报告直接使用,而是由嵌入在水晶报告中的查询或者在中使用的存储过程中使用。水晶报告。

这是使用表(SomeOtherTable)来实现的,只要报告在运行之后保存参数数据,之后数据就会被删除,因此我们可以假设SomeOtherTable在任何给定的时间点都有最多2到3行。 / p>

因此,如果我们查看上面的查询,可以将Query的初始部分假设为Report Query,并使用where子句从SomeOtherTable表中获取用户输入。

所以我认为创建索引等不会有用(可能是我错了)。

9 个答案:

答案 0 :(得分:3)

  

SomeOtherTable没有   索引或任何约束所有字段   是char(50)

嗯,这是你的问题。对于像这样的查询,您无法做任何事情,如果您像这样创建它,它将改善其性能。

  • 您需要在所有表格上指定正确的主要或其他候选键。也就是说,您需要在表格上至少有一个唯一索引。您可以通过将一个或多个字段指定为PK来执行此操作,也可以添加UNIQUE约束或索引。

  • 您需要正确定义字段。该字段是否存储整数?那么,INT字段可能比CHAR(50)更好。

您无法“优化”基于不健全架构的查询。

答案 1 :(得分:2)

尝试:

SELECT
    *
FROM
    SomeTable
LEFT JOIN SomeOtherTable ON SomeTable.ID=SomeOtherTable.ID AND Name = 'ABC'
WHERE
    1=1 
AND
(
SomeOtherTable.ID IS NOT NULL
OR
0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC')
)

答案 2 :(得分:1)

还在每个表名后加上'with(nolock)'来提高性能

答案 3 :(得分:1)

以下内容可能会加快您的速度

SELECT * 
FROM SomeTable 
WHERE
   SomeTable.ID in 
        (SELECT DISTINCT ID FROM SomeOtherTable Where Name = 'ABC')
UNION
SELECT * 
FROM SomeTable 
Where 
   NOT EXISTS (Select spName From SomeOtherTable Where spName = 'ABC')

UNION将有效地将其拆分为两个更简单的查询,这些查询可以单独进行优化(很大程度上取决于DBMS,表大小等是否真的会提高性能 - 但总是值得一试)。

“EXISTS”关键字比“SELECT COUNT(1)”更有效,因为一遇到第一行就会返回true。

答案 4 :(得分:1)

或者先检查db中是否存在该值 您可以在查询中删除distinct关键字,这里没用。

如果EXISTS(从SomeOtherTable中选择spName,其中spName ='ABC') 开始     选择 *     来自SomeTable     哪里    SomeTable.ID in         (SELECT Name FROM SomeOtherTable Where Name ='ABC') 结束 其他 开始     选择 *     来自SomeTable 端

答案 5 :(得分:0)

阿罗哈

尝试

select t.* from SomeTable t
    left outer join SomeOtherTable o
        on t.id = o.id
where (not exists (select id from SomeOtherTable where spname = 'adbc')
OR spname = 'adbc')

-Edoode

答案 6 :(得分:0)

将where部分中的所有select语句更改为内部jons。 OR条件应该是union all-ed。 还要确保您的索引正常。

有时候为你可以加入的临时结果有一个中间表是值得的。

答案 7 :(得分:0)

感谢大家的建议。我将坚持原来的查询。

答案 8 :(得分:0)

在我看来,您的查询中不需要“1 = 1 AND”。 1 = 1将始终评估为真,让软件评估下一部分...为什么不跳过1 = 1并评估多汁部分?