代码之家  ›  专栏  ›  技术社区  ›  Prescott

对于某些标准的WHERE子句,SQL Server 2005似乎永远都需要。

  •  0
  • Prescott  · 技术社区  · 15 年前

    这是我的表模式

    [dbo].[Action_History](
        [ActionID] [int] IDENTITY(1,1) NOT NULL,
        [objectID] [int] NOT NULL,
        [object_mask] [varchar](max) NULL,
        [description] [varchar](max) NOT NULL,
        [action_by] [nchar](7) NOT NULL,
        [action_date] [datetime] NOT NULL,
        [response_required] [bit] NOT NULL,
        [responded_date] [datetime] NULL,
        [responded_by] [nchar](7) NULL,
        [recurring] [bit] NULL CONSTRAINT [DF_Action_History_recurring]  DEFAULT ((0)),
        [actionTypeID] [int] NULL,
        [target_user] [nchar](7) NULL,
        [target_role] [varchar](25) NULL,
        [object_type] [varchar](30) NULL, CONSTRAINT [PK_Action_History] PRIMARY KEY CLUSTERED 
    

    这里是查询1:

    SELECT    
        Top(1) 
        ActionID, objectID, object_mask, 
        [description], action_by, action_date, response_required, 
        responded_date, responded_by, recurring, actionTypeID, 
        target_user, target_role, object_type
    FROM
        Action_History
    WHERE     
        ((objectID = 201006)
        AND (responded_date is null)    
        AND (object_type = 'MyType'))
    

    查询2:

    SELECT    
        Top(1) 
        ActionID, objectID, object_mask, 
        [description], action_by, action_date, response_required, 
        responded_date, responded_by, recurring, actionTypeID, 
        target_user, target_role, object_type
    FROM
        Action_History
    WHERE     
        ((objectID = 201006)
        AND (responded_date is null)    
        AND (object_type = 'Mytype')
        AND (actionTypeID = 55) 
        AND (response_required = 1))
    

    查询1将在0秒内加载,但查询2无法返回结果。WHERE子句中最后2个条件和条件之一将导致查询挂起。另外,如果我只有2-5个条件(没有objectid),那么它的运行速度似乎也一样快。

    我需要查询2来处理所有的条件。有什么想法吗?

    谢谢,

    ~P

    编辑: 如果objectid不存在,则第二个查询似乎挂起,但如果存在,则加载没有问题。

    编辑2: 我有一个关于actionid的索引,我知道在这种情况下它并没有太大的帮助。我现在也没有能力创建任何其他索引(把它塞进过度保护的数据库安全中)。

    我对db-stuff很糟糕,但是当我从“显示的估计执行计划”中浏览聚集索引扫描两个不同的查询时,我看到的只是一个稍微不同的谓词,它看起来与我的谓词完全相同,可能不是正确的执行计划…

    编辑3: 执行计划-它们看起来很相似,除了缺少条件的2个。此外,如果有结果,我的第二个查询似乎是在没有时间限制的情况下运行的。如果没有结果,它将永远运行(有一个值相同的记录,但objectid是201002而不是201006)。而且我们的通话记录还不到4K。

      |--Top(TOP EXPRESSION:((1)))
           |--Clustered Index Scan(OBJECT:([db].[dbo].[Action_History].[PK_Action_History]), 
                                    WHERE:([db].[dbo].[Action_History].[objectID]=(201002) AND 
                                           [db].[dbo].[Action_History].[responded_date] IS NULL AND 
                                           [db].[dbo].[Action_History].[actionTypeID]=(55) AND 
                                           [db].[dbo].[Action_History].[response_required]=(1) AND 
                                           [db].[dbo].[Action_History].[object_type]='MyType'))
    

    编辑4: 看起来在第二个数据库上运行我的第二个查询(有51K条记录)运行得很好。我不知道这两个数据库之间的区别,我有没有想过如何解决这个问题?

    4 回复  |  直到 15 年前
        1
  •  1
  •   zarko.susnjar    15 年前

    打开执行计划显示并检查Management Studio是否在建议某些内容。在这些列上创建索引。

    如果这不起作用,请创建CREATETABLE语句并将其发布到此处以检查数据类型和索引。

        2
  •  1
  •   SQLMenace    15 年前

    你有关于actiontypeid和response_的索引吗?比较两个查询之间的执行计划

    要查看执行计划的文本版本,请在查询之前运行以下内容

    SET SHOWPLAN_TEXT ON
    GO
    

    以后再关掉它

    SET SHOWPLAN_TEXT OFF
    GO
    
        3
  •  0
  •   Beth    15 年前

    在要用作WHERE子句、排序或与其他表的关系条件的任何字段上添加索引。

    另外,尝试不带顶部(1)。如果只需要第一个结果,可以进行排序,但如果这将结果限制为1行,则可以隐藏查询中的错误。

        4
  •  0
  •   Prescott    15 年前

    结果发现一个或多个行已损坏,所以当数据库扫描到这些行时,它会冻结/循环,或者其他什么。谢谢大家的帮助。

    推荐文章