1

首先:我不是一个DB专家,所以请尽情享受,如果问题很琐碎...火鸟2.5 SQL查询执行计划不使用索引或声明

我有一个子表CHILD查询寻找在主表PARENT中增加一些值以确定是否要加载条目。

查询看起来像这样

SELECT C.*, P.DATE, P.STATUS 
FROM CHILD C, PARENT P 
WHERE C.PARENT_ID = P.ID 
AND (P.DATE > '01.01.2015' OR (P.STATUS <> 1 AND P.STATUS <> 9)); 

我选择的目的STATUS价值观强调的是,我需要使用的不平等,我需要选择从是不连续的状态值。

我对PARENT.ID有外键CHILD.PARENT_ID,并创建了一个索引CHILD.PARENT_ID。我还在和STATUS字段的表PARENT上创建了索引。

现在,当我更换OR与和ANDCHILD使用上PARENT_IDPARENT索引使用上DATE, STATUS这是我所期望的指数。

但是,当使用OR时,查询使用CHILD上的自然计划和PARENT.ID上的主键索引。

发生同样,如果我申请查询仅父表:

SELECT P.* FROM PARENT P WHERE (P.DATE > '01.01.2015' OR (P.STATUS <> 1 AND P.STATUS <> 9)); 

有没有办法来优化这样的查询使用比天然计划好?

+0

你能否在这里更新两个计划:http://www.brentozar.com/pastetheplan/ ..此外,表格数量, – TheGameiswar

+0

这两个表上的索引请标记您正在使用的数据库。 –

+0

请编辑您的问题,为所讨论的表(包括所有索引)和执行计划添加'create table'语句。 [_Formatted_](http://stackoverflow.com/help/formatting)**文本**请[无屏幕截图](http://meta.stackoverflow.com/questions/285551/why-may-i-not -upload图像-的代码上那么当-要价-A-问题/ 285557#285557) –

回答

2

如果你写'或',每个P.DATE可能是一个命中。每个P.STATUS也可能是一个命中。如果你想使用索引,这不是很好的先决条件。

在这里,你必须帮助你的系统,并提出两个单独的问题,并将它们与UNION连接起来。 Like

SELECT C.*, P.DATE, P.STATUS 
    FROM CHILD C, PARENT P 
WHERE C.PARENT_ID = P.ID 
    AND P.DATE > '01.01.2015' 
UNION 
SELECT C.*, P.DATE, P.STATUS 
    FROM CHILD C, PARENT P 
WHERE C.PARENT_ID = P.ID 
    AND P.STATUS <> 1 
    AND P.STATUS <> 9; 

注意:如果P.STATUS的大多数值不等于1且不等于9,那么您的性能仍然不佳。试想一下,你正在查找一本书,所有单词都被编入索引中,并用于“和”这个词。它将在每一页;按顺序读书会比使用索引更快。

2

这对于优化器在其上使用索引可能相当困难。首先,使用join来重写查询:

SELECT C.*, P.DATE, P.STATUS 
FROM CHILD C JOIN 
    PARENT P 
    ON C.PARENT_ID = P.ID 
WHERE P.DATE > '2015-01-01' OR P.STATUS NOT IN (1, 9); 

你可以重写这个使用UNION ALL

SELECT C.*, P.DATE, P.STATUS 
FROM CHILD C JOIN 
    PARENT P 
    ON C.PARENT_ID = P.ID 
WHERE P.DATE > '2015-01-01' 
UNION ALL 
SELECT C.*, P.DATE, P.STATUS 
FROM CHILD C JOIN 
    PARENT P 
    ON C.PARENT_ID = P.ID 
WHERE P.DATE <= '2015-01-01' AND -- This condition prevents overlaps 
     P.STATUS NOT IN (1, 9); 

子查询现在可以利用索引对PARENT(DATE, ID)PARENT(STATUS, DATE, ID)

但是,过滤结果实际上会使查询更快,这并不明确。这取决于过滤器的选择性。