SQL Server分区和索引

时间:2017-06-20 10:53:04

标签: sql sql-server

我需要设计一个大约有8000万条记录的表。我使用持久列为每个月创建一个分区(如果它的错误提示我最好的方法)。请查找下面用于创建表和分区的脚本以及经常使用的查询。此表仅进行插入和删除。

-- Create the Partition Function 
   CREATE PARTITION FUNCTION PF_Invoice_item (int)
   AS RANGE LEFT FOR VALUES (1,2,3,4,5,6,7,8,9,10,11,12);

-- Create the Partition Scheme
   CREATE PARTITION SCHEME PS_Invoice_item
   AS PARTITION PF_Invoice_item ALL TO ([Primary]);



   CREATE TABLE [Invoice]
   (
   [invoice_id] [bigint] NOT NULL,
   [Invoice_Number] [varchar](255) NULL,
   [Invoice_Date] [date] NULL,
   [Invoice_Total] [numeric](18, 2) NULL,
   [Outstanding_Balance] [decimal](18, 2) NULL,
   CONSTRAINT [PK_Invoice_id] PRIMARY KEY CLUSTERED([invoice_id] ASC)
   )



  CREATE TABLE [InvoiceItem](
  [invoice_item_id] [bigint] NOT NULL,
  [invoice_id] [bigint] NOT NULL,
  [invoice_Date] [date] NULL,
  [make] [varchar](255) NULL,
  [serial_number] [varchar](255) NULL,
  [asset_id] [varchar](100) NULL,
  [application] [varchar](255) NULL,
  [customer] [varchar](255) NULL,
  [ucid] [varchar](255) NULL,
  [dcn] [varchar](255) NULL,
  [dcn_name] [varchar](255) NULL,
  [device_serial_number] [varchar](255) NULL,
  [subscription_name] [varchar](255) NULL,
  [product_name] [varchar](255) NULL,
  [subscription_start_date] [date] NULL,
  [subscription_end_date] [date] NULL,
  [duration] [varchar](50) NULL,
  [promo_name] [varchar](255) NULL,
  [promo_end_date] [date] NULL,
  [discount] [decimal](18, 2) NULL,
  [tax] [decimal](18, 2) NULL,
  [line_item_total] [decimal](18, 2) NULL,
  [mth]  AS (datepart(month,[invoice_date])) PERSISTED NOT NULL,**
  [RELATED_PRODUCT_RATEPLAN_NAME] [varchar](250) NULL,
  [SUB_TOTAL] [decimal](18, 2) NULL,
  [BILLING_START_DATE] [date] NULL,`enter code here`
  [BILLING_END_DATE] [date] NULL,
  [SUBSCRIPTION_ID] [varchar](200) NULL,
  [DEVICE_TYPE] [varchar](200) NULL,
  [BASE_OR_PROMO] [varchar](200) NULL,
  CONSTRAINT [PK_InvoiceItem_ID] PRIMARY KEY CLUSTERED ([invoice_item_id] 
  ASC,[mth] ASC))
  ON PS_Invoice_item(mth);
  GO



 ALTER TABLE [InvoiceItem]  WITH CHECK ADD  CONSTRAINT [FK_Invoice_ID] 
 FOREIGN KEY([invoice_id])
 REFERENCES [Invoice] ([invoice_id])

GO

我将使用以下查询

select subscription_name,duration,start_date,end_date,promotion_name,
promotion_end_date,sub_total,discount,tax,line_item_total from InvoiceItem 
lt inner join Invoice on lt.invoice_id=invoice.invoice_id where 
invoice.invoice_number='' and lt.customer='' and lt.ucid='' lt.make='' and 
lt.SERIAL_NUMBER='' and lt.dcn='' and lt.application=''

select customer,make,application from billing.AssetApplicationTotals 
lineItem inner join billing.Invoice invoice on 
lineItem.invoice_id=invoice.invoice_id where invoice.invoice_number='';

SELECT  [invoice_Date],[make],[serial_number],[application],[customer],
[ucid],[dcn],[dcn_name],[device_serial_number]
,[subscription_name],[product_name],[subscription_start_date],
[subscription_end_date],[duration],[promo_name],[promo_end_date]
FROM [InvoiceItem] where [application]=''

SELECT  [invoice_Date],[make],[serial_number],[application],[customer],
[ucid],[dcn],[dcn_name],[device_serial_number]
,[subscription_name],[product_name],[subscription_start_date],
[subscription_end_date],[duration],[promo_name],[promo_end_date]
FROM [InvoiceItem] where [customer]=''

创建索引的最佳方法是什么?我应该为每个过滤器创建单独的非聚集索引,还是我应该有复合索引,并且我是否应该覆盖索引以避免密钥查找?

1 个答案:

答案 0 :(得分:0)

按照问题的陈述:“只会在此表上执行插入和删除操作”,在这种情况下,我认为您不需要任何分区。如果您要根据任何特定条件或特定列频繁或批量执行任何删除操作,则对该列进行分区可能会有所帮助,但是再次需要在该查询的``where''条件下指定该列。 / p>

'select'操作(如果您正在计划)(我相信是这样),您可以再次对该列进行分区,然后将其置于'select'查询的'where'条件中。

索引:索引创建应再次基于要在该表上执行的基础查询来完成。您需要首先分析该表上经常查询哪种类型的列/哪种顺序/什么列。如果要频繁查询广泛的列集,则宽索引可能会提供良好的结果。您可能必须进行实验找到最有效的索引之前的几种不同设计。可以添加,修改和删除索引,而不会影响数据库架构或应用程序设计。因此,您应该毫不犹豫地尝试使用不同的索引。确定索引的最佳存储位置。非聚集索引可以存储在与基础表相同的文件组中,也可以存储在不同的文件组中。索引的存储位置可以通过提高磁盘I / O性能来提高查询性能。例如,在与表文件组不同的磁盘上的文件组中存储非聚集索引可以提高性能,因为可以同时读取多个磁盘