2011-08-20 91 views
0

我有以下两个表:SQL:关于查询优化的问题

CREATE TABLE Test_Main 
    (
     [ID] INT IDENTITY , 
     [TypeID] INT , 
     [BookID] INT 
    ) 

CREATE TABLE Test_Second 
    (
     [TypeID] INT , 
     [BookID] INT , 
     [Value] INT, 

    ) 

INSERT INTO Test_Main(TypeID, BookID) 
    SELECT 1, 10 
    UNION 
    SELECT 2, 31 
    UNION 
    SELECT 3, 51 
    UNION 
    SELECT 4, 81 

INSERT INTO Test_Second(TypeID, BookID, Value) 
    SELECT 1, 0, 30 
    UNION 
    SELECT 2, 31, 45 
    UNION 
    SELECT 3, 51, 66 
    UNION 
    SELECT 4, 0, 22 

,我有以下查询:

SELECT 
    ID , 
    Test_Main.TypeID , 
    Test_Main.BookID 
FROM 
    Test_Main 
INNER JOIN 
    Test_Second ON Test_Main.[TypeID] = Test_Second.[TypeID] 
WHERE 
    Test_Main.BookID = CASE WHEN (Test_Main.BookID = 2 OR Test_Main.BookID = 3) 
           THEN Test_Second.BookID 
          ELSE Test_Main.BookID 
         END 

这个查询是给下面的输出:

ID   TypeID  BookID 
----------- ----------- ----------- 
1   1   10 
2   2   31 
3   3   51 
4   4   81 

现在,当我的表有100万行时,我怀疑我的case子句会导致性能问题。我如何优化查询以使用索引查找。上述查询的索引应该是什么?

回答

2

你需要有适当的指标到位:

  • TypeID应在两个表进行索引(因为它在连接状态下使用)
  • Test_Main.BookID需要被索引,因为它的在WHERE子句中使用

有了这三个索引,我相信你的查询应该可以很好地工作,即使表中有很多行!

+0

你认为'(TypeID,BookID)'上的compoun索引会被使用吗(并有助于提高效率)? –

+0

@ypercube:它将用于'TypeID'上的查询 - 但添加'BookID'并不真正有帮助,我会想;这个复合索引可能**不能用于单独使用'BookID'的查询。 –

0

(问:你确定你不是说TypeID而不是BookID在这一部分?):

... WHEN (Test_Main.TypeID = 2 OR Test_Main.TypeID = 3) 

你的查询等效于:

SELECT 
    ID , 
    Test_Main.TypeID , 
    Test_Main.BookID 
FROM 
    Test_Main 
INNER JOIN 
    Test_Second ON Test_Main.[TypeID] = Test_Second.[TypeID] 
WHERE 
    (Test_Main.BookID IN (2,3) 
     AND Test_Main.BookID = Test_Second.BookID 
    ) 
    OR Test_Main.BookID NOT IN (2,3) 

除了指标,你也可以检查这个版本的执行计划(以防万一,我不确定CASE子句可以优化多少)。