一旦表变大,我可以做些什么来提高未来的性能?

ana*_*123 2 database-design sql-server index-tuning sql-server-2012

我创建了一个导入 600,000 行 Excel 工作表的表格。我将运行的大多数查询都将使用C_CustomerID,它们将如下例所示:

select * from testtable where C_CustomerID = 12345678
Run Code Online (Sandbox Code Playgroud)

表定义为:

CREATE TABLE [dbo].[testtable](
    [id_card] [int] IDENTITY(1,1) NOT NULL,
    [C_CustomerID] [int] NOT NULL,
    [C_AccountID] [nvarchar](255) NULL,
    [C_ProductID] [varchar](20) NULL,
    .......... more columns here ...     
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

我创建了一个索引:

CREATE NONCLUSTERED INDEX [inx_profitability] ON [dbo].[testtable]
(
    [C_CustomerID] ASC
)
Run Code Online (Sandbox Code Playgroud)

稍后我只会从 Excel 工作表导入更多记录。每 6 个月将导出约 500,000 条新记录。

一旦表变大,我可以做些什么来提高未来的性能?

我正在运行 SQL Server 2012 和 Microsoft SQL Server Management Studio 11.0.3128.0。

Pau*_*ite 6

如果所有查询都是以下形式:

select * from testtable where C_CustomerID = 12345678
Run Code Online (Sandbox Code Playgroud)

那么你已经拥有的也不是完全没有道理的。从基表(当前为堆)检索非聚集索引未涵盖的列是有成本的,但除非每个 有很多行C_CustomerID,否则这可能不是一个实际问题。

也就是说,目前的安排并不理想。SQL Server 有可能决定扫描整个堆以查找匹配项,而不是搜索非聚集 b 树索引,然后执行多个单行查找。

在没有任何其他考虑的情况下,我可能会用(非唯一)聚集索引替换非聚集索引:

DROP INDEX inx_profitability ON dbo.testtable;
GO
CREATE CLUSTERED INDEX [CX dbo.testtable C_CustomerID]
ON dbo.testtable (C_CustomerID);
Run Code Online (Sandbox Code Playgroud)

聚集索引定义了表中行的逻辑顺序,并提供对整行的直接访问(因此不需要查找)。在很大程度上,聚集索引在很大程度上是“免费的”,因为它不是带有(部分)数据副本的单独结构。

对于具有相同C_CustomerID. 您不能直接引用此值,但它确实会增加一些开销。

如果您删除行(问题提到导出),则将其设为聚簇表(通过添加聚簇索引)也可能会改善表的未使用的未来空间管理。

您可以选择在上面的聚集索引构建上(以及在执行维护时)指定填充因子,例如通过添加WITH (FILLFACTOR = 70). 这将在叶级保留一定比例的空闲空间以供将来插入(请记住,行和页按 逻辑排序C_CustomerID)。70 的选择完全是任意的。您选择的值(如果有)完全取决于情况。如果所有查询都如上所示,则可能几乎不需要指定填充因子。

原则上,每个表都应该有一个键(主键或其他键),以强制执行任何真实世界的列组合唯一标识每一行。在您的情况下,这可能是非聚集主键或唯一约束。