我有以下查询(稍作修改为清楚起见)子查询:查询与WHERE子句不断超时
CREATE PROCEDURE Kctc.CaseTasks_GetCaseTasks
@CaseNumber int
... other parameters
,@ChangedBefore datetime
,@ChangedAfter datetime
AS
SELECT Kctc.CaseTasks.CaseTaskId
...blah blah blah
FROM Kctc.CaseTasks
... some joins here
WHERE
... some normal where clauses
AND
(
(@ChangedAfter IS NULL AND @ChangedBefore IS NULL)
OR
EXISTS (SELECT *
FROM Kctc.FieldChanges
WHERE Kctc.FieldChanges.RecordId = Kctc.CaseTasks.CaseTaskId AND
Kctc.FieldChanges.TableName = 'CaseTasks' AND
Kctc.FieldChanges.DateOfChange BETWEEN
ISNULL(@ChangedAfter, '2000/01/01') AND
ISNULL(@ChangedBefore, '2050/01/01'))
)
此查询超时每当用户指定值@ChangedBefore
或@ChangedAfter
,因此调用子查询。
子查询检查表FieldChanges
中的记录是否存在(它有效记录对CaseTasks
表中每个字段的更改)。
查询FieldChanges
效率不高,因为它涉及对未编入索引的文本字段TableName
进行过滤。而且我知道子查询本质上是无效的。
所以我的问题总的来说是有没有办法重新设计查询,使其表现更好?
当有多个相关FieldChanges
(即保留EXISTS语义),我不能想办法来表达子查询作为一个联接,同时仍只返回一个CaseTask
一行。我还没有索引FieldChanges
表的TableName
字段,因为我对索引文本字段犹豫不决。
那我该怎么办?
顺便说一句,我可以看到数据库的设计可能需要审查,因为它似乎不能处理当前的数据量。但我的问题是关于查询的设计,而不是数据库的设计。 – David 2011-05-18 10:47:31
我们正在寻找CaseTasks和FieldChanges的行数。你现在还有什么样的索引。 – JStead 2011-05-18 11:43:05
最好的办法是评估查询计划。这将告诉你,你是否正在进行全盘扫描,你不希望这样做。 – 2011-05-18 11:45:42