SQL Server不会为查询选择最佳索引

时间:2014-11-29 18:43:54

标签: sql-server sql-server-2008

我正在尝试优化从COTS应用程序创建的SQL Server查询。因此,我无法更改生成的SQL查询,必须完全依赖SQL Server查询优化器。

生成的查询看起来像这样(我很抱歉乱搞SQL。它是由应用程序生成的,我无法影响它):

SELECT DISTINCT 
    t_02.puid, t_02.pac4_itemId 
FROM 
    PWORKSPACEOBJECT t_01, PAC4_DESIGNSOLREVISION t_02 
WHERE 
    ( ( ( ( t_01.pactive_seq != 0 ) AND 
          ( t_01.pdate_released > CONVERT(datetime, '2011-12-31 23:00:00', 120) ) 
        ) 
        AND t_02.puid IN ( ( ( (SELECT t_03.puid 
                                FROM PAC4_DESIGNSOLREVISION t_03 
                                WHERE  UPPER(t_03.pac4_itemId)  LIKE  UPPER( '%0000%' )
UNION ALL
SELECT t_05.puid FROM PWORKSPACEOBJECT t_04 , PAC4_DESIGNSOLREVISION t_05 WHERE (  UPPER(t_04.pobject_name)  LIKE  UPPER( '%0000%' )  AND ( t_04.puid = t_05.puid ) ) )
UNION ALL
SELECT t_06.puid FROM PAC4_DESIGNSOLREVISION t_06 , PITEMREVISION t_07 WHERE (  UPPER(t_07.pitem_revision_id)  LIKE  UPPER( '%0000%' )  AND ( t_06.puid = t_07.puid ) ) )
UNION ALL
SELECT t_09.puid FROM PWORKSPACEOBJECT t_08 , PAC4_DESIGNSOLREVISION t_09 WHERE (  UPPER(t_08.pobject_type)  LIKE  UPPER( '%0000%' )  AND ( t_08.puid = t_09.puid ) ) )  ) ) AND ( t_01.puid = t_02.puid ) )

此查询需要9秒才能执行。

我使用以下语句创建了一个新索引:

    CREATE NONCLUSTERED INDEX [AC_ItemId] ON [dbo].[PAC4_DESIGNSOLREVISION] 
    (
        [pac4_itemId] ASC
    )
    INCLUDE ( [puid]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    GO

之后我测试了相同的查询,优化器没有选择索引。它更喜欢聚集索引。查询仍需要9秒钟才能完成。

然后我暗示查询使用我的新索引" with(index(AC_ItemId))":

SELECT  DISTINCT t_02.puid, t_02.pac4_itemId FROM PWORKSPACEOBJECT t_01 , PAC4_DESIGNSOLREVISION t_02 WHERE ( ( ( ( t_01.pactive_seq != 0 ) AND ( t_01.pdate_released > CONVERT(datetime, '2011-12-31 23:00:00', 120) ) ) AND t_02.puid IN  (  (  (  ( SELECT t_03.puid FROM PAC4_DESIGNSOLREVISION t_03 **with (index(AC_ItemId))** WHERE  UPPER(t_03.pac4_itemId)  LIKE  UPPER( '%0000%' )
UNION ALL
SELECT t_05.puid FROM PWORKSPACEOBJECT t_04 , PAC4_DESIGNSOLREVISION t_05 WHERE (  UPPER(t_04.pobject_name)  LIKE  UPPER( '%0000%' )  AND ( t_04.puid = t_05.puid ) ) )
UNION ALL
SELECT t_06.puid FROM PAC4_DESIGNSOLREVISION t_06 , PITEMREVISION t_07 with (index(AC_RevId)) WHERE (  UPPER(t_07.pitem_revision_id)  LIKE  UPPER( '%0000%' )  AND ( t_06.puid = t_07.puid ) ) )
UNION ALL
SELECT t_09.puid FROM PWORKSPACEOBJECT t_08 , PAC4_DESIGNSOLREVISION t_09 WHERE (  UPPER(t_08.pobject_type)  LIKE  UPPER( '%0000%' )  AND ( t_08.puid = t_09.puid ) ) )  ) ) AND ( t_01.puid = t_02.puid ) )

通过此添加,查询需要0秒才能执行。

如果从COTS应用程序运行查询而无法更改生成的查询,如何告诉SQL Server优化器选择此索引?

更新1:

如果我独立运行子SQL语句,优化器会选择非聚集索引。将子SQL放在完整SQL语句的上下文中时会出现问题。

这是提到的子SQL:

SELECT t_03.puid 
FROM PAC4_DESIGNSOLREVISION t_03 
WHERE UPPER(t_03.pac4_itemId) LIKE UPPER('%0000%')

1 个答案:

答案 0 :(得分:0)

添加一个复合索引,其中包含您引用的所有或大多数字段,直到优化程序确定这是要使用的相应索引。