2017-02-13 121 views
0

表大小32GB 行数250M如何提高SQL Server查询性能

表DDL

CREATE TABLE Orders 
(
    ID [int] IDENTITY(1,1) NOT NULL, 
    server [varchar](50) NULL, 
    server_id [int] NOT NULL, 
    merchant_id [int] NOT NULL, 
    order_id [int] NOT NULL, 
    customer_id [int] NOT NULL, 
    customer_name [varchar](50) NULL, 
    [amount] [money] NULL, 
    order_date [smalldatetime] NULL, 
    ship_date [smalldatetime] NULL, 
    order_status [varchar](50) NULL,  
    custom_field_1 [varchar](50) NULL, 
    custom_field_2 [varchar](50) NULL, 
    custom_field_3 [varchar](50) NULL, 
    custom_field_4 [varchar](50) NULL, 
    created_at [datetime] NULL 

    CONSTRAINT [PK_Orders] 
     PRIMARY KEY CLUSTERED ([ID] ASC) 
        WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
          ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

我有以下的非聚集索引

merchant_id, order_id 
order_date 

从逻辑上讲,order_idmerchant_id做一个独特的钥匙。

像下面简单的查询需要近30分钟。

select 
    sum(amount) 
from 
    Orders 
where 
    Order_Date >= getdate() - 7 

我有几个问题:

  • 是的PK吗?目前它在ID字段上,并没有被用于任何事情。
  • 将使得order_idmerchant_id在性能PK的帮助?
  • 什么是理想的指标,我应该对这个表?
+1

您应该在'Order_Date'上创建一个索引,如果它包含'amount',则更好。 – Lamak

+1

什么是查询计划? – Paurian

+1

注意到您的表的大小和行数,您可能需要采取SqlZim建议的操作,并根据写入该表的流量来定期重建索引以减少碎片。 – Paurian

回答

1

是PK的,对吗?

也许。使用这种替代id聚类密钥通过使用薄的4个字节的密钥代替merchant_id, order_id

聚集键的merchant_id, order_id, order_date或8字节的密钥的复合12字节的密钥的保持存储所有索引的开销下是如何每索引指向表格的其余部分。

将使得ORDER_ID和MERCHANT_ID在性能PK的帮助?

您将不得不查看对该表运行的所有查询的影响,以了解它是否有帮助。

我将专注于评估覆盖索引,你需要运行速度更快的查询,如果你发现了一个趋势,你需要这两列于大多数的查询,那么也许。

什么是理想的指标,我应该对这个表?

您需要查看查询,执行计划和当前索引使用情况,以确定该表需要哪些索引。


由于您的order_date是不是在你的非聚集索引的第一列,优化器将最有可能无法将其用于您的示例查询。

即使您有一个order_date的索引,它也必须返回表格才能获得amount。如果在索引中包含amount作为包含列,它将成为该查询的覆盖索引,无需返回表格。

对于例如查询,你可以使用这样的事情有一个仅索引查询,而不是一个一个查找表:

create nonclustered index ix_Orders (Order_Date) include (amount);