【问题标题】:Performance in SQL ServerSQL Server 中的性能
【发布时间】:2013-04-16 15:03:30
【问题描述】:

我在对 mssql 2008 数据库运行查询的程序中遇到问题。 我在查询分析器中做了一些研究。 以下两个查询有一个奇怪的问题:

SELECT  BOLD_ID ,
        BOLD_TYPE
FROM    ZusatzKlasseBase
WHERE   ( bold_id IN ( SELECT   usereintrag
                       FROM     zusatzfeld
                       WHERE    metazusatzfeld = 5211309
                                AND wertobject = 1298369 )
          AND bold_id IN ( SELECT   usereintrag
                           FROM     zusatzfeld
                           WHERE    metazusatzfeld = 5207783
                                    AND wertdatum = '20130415' )
        )

这个查询的运行时间大约是一秒

SELECT  BOLD_ID ,
        BOLD_TYPE
FROM    ZusatzKlasseBase
WHERE   ( BOLD_TYPE IN ( 336 ) )
        AND ( bold_id IN ( SELECT   usereintrag
                           FROM     zusatzfeld
                           WHERE    metazusatzfeld = 5211309
                                    AND wertobject = 1298369 )
              AND bold_id IN ( SELECT   usereintrag
                               FROM     zusatzfeld
                               WHERE    metazusatzfeld = 5207783
                                        AND wertdatum = '20130415' )
            )

这个查询的运行时间是一分钟。

对此我没有解释,字段 BOLD_TYPE 已编入索引。 谁能猜出为什么更具体的查询更慢?

提前感谢所有答案。

【问题讨论】:

  • 只是出于兴趣,为什么要执行两次select usereintrag from zusatzfeld where ... 代码?为什么不用多组逻辑标准来优化代码呢?
  • 执行计划有何不同?
  • 那么,BOLD_TYPE 上有索引吗?表中有多少行?有多少行的值为 336?
  • @Westie SQL 语句由标准 erp 软件生成。这样做的原因是,它是通用代码。如果我知道原因,我可以要求更改。
  • @Westie 这似乎并不是真正的问题,因为第一个查询执行得“足够好” - 结合逻辑可能只是让优化器适合试图提出一个完美的计划满足任一条件。我首先建议将IN 更改为相关的EXISTS,因为这可能会提供更明显的好处,并且可能更容易合并到 ERP 代码中。

标签: sql performance sql-server-2008


【解决方案1】:

我会将bold_id 上的索引(我假设bold_id 上有一个索引)更改为:

CREATE INDEX whatever ON dbo.ZusatzKlasseBase(bold_id, bold_type)
  WITH (DROP_EXISTING = ON);

那我稍微重写一下查询:

SELECT  BOLD_ID,
        BOLD_TYPE
FROM dbo.ZusatzKlasseBase AS b -- always use schema prefix
WHERE
    ( BOLD_TYPE IN ( 336 ) )
    AND EXISTS 
    (
      SELECT 1 FROM dbo.zusatzfeld
      WHERE    metazusatzfeld = 5211309
               AND wertobject = 1298369 
               AND usereintrag = b.bold_id
    )
    AND EXISTS
    ( 
       SELECT 1 FROM dbo.zusatzfeld
       WHERE    metazusatzfeld = 5207783
                AND wertdatum = '20130415' 
                AND usereintrag = b.bold_id
    );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多