【问题标题】:sql: question regarding query optimizationsql:关于查询优化的问题
【发布时间】:2011-10-31 04:59:39
【问题描述】:

我有以下两张表:

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

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

【问题讨论】:

    标签: sql sql-server sql-server-2005 indexing


    【解决方案1】:

    您需要有适当的索引:

    • TypeID 列应在两个表上都建立索引(因为它用于 JOIN 条件)
    • Test_Main.BookID 列需要建立索引,因为它用于 WHERE 子句中

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

    【讨论】:

    • 您认为(TypeID, BookID) 上的复合索引会被使用(并有助于提高效率)吗?
    • @ypercube:它将用于查询TypeID - 但我认为添加BookID 并没有真正的帮助;此复合索引不能用于单独使用 BookID 的查询....
    【解决方案2】:

    (问题:你确定你在这部分不是指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子句可以优化到什么程度)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      相关资源
      最近更新 更多