我对选择正确的索引有一些疑问,并有一些问题:
聚集索引
最佳人选是什么?
通常是主键但是如果主要密钥未在搜索中使用,例如CustomerNo
用于搜索客户,那么聚集索引应该放在CustomerNo
上吗?
使用SchemaBinding查看
如果有一个带索引的视图,我读到这些没有被使用,但是那些在表上是。
毫无意义?或者我错过了这一点?使用“NOExpand”强制从视图而不是表中读取索引会有所不同吗?
非聚集索引
添加非聚集索引以包含每个可能的列,直到达到限制为止,这是不错的做法?
非常感谢你的时间。我正在阅读海量数据库,速度是必须的
答案 0 :(得分:8)
聚集索引是(a)定义表的存储布局(表数据按聚类键物理排序)的索引,(b)用作“行”定位器“在该表的每个非聚集索引中。
因此,聚集索引应为
Varchar(x)
列在这些要求中,INT IDENTITY
似乎是最合乎逻辑,最明显的选择。不要使用可变长度的列,不要使用多个列(如果可能的话),不要使用 GUID (这是一个非常糟糕的选择,因为它的大小和随机性)
有关群集密钥和聚簇索引的更多背景信息 - 阅读Kimberly Tripp发布的所有内容!她是SQL Server中的索引女王 - 她非常了解她的东西!
参见例如这些博文:
一般来说:不要过度索引!过多的索引往往比没有索引更糟糕!
对于非聚集索引:我通常会索引外键列 - 这些索引有助于JOIN和其他操作,并使事情更快。
除此之外:不要在数据库中放入太多索引!必须在桌面上的每个CRUD操作上维护每个索引!这是开销 - 不要过度索引!
表的所有列的索引是特别糟糕的主意,因为它确实不能用得太多 - 但会带来很多管理开销。
运行您的应用,对其进行分析 - 查看哪些操作很慢,尝试通过在表中添加一些选择性索引来优化这些操作。
答案 1 :(得分:2)
群集索引
只是要添加到marc_s
一个好的答案,对于群集索引的标准INT IDENTITY PK
方法的一个例外是,当您有Parent
Child
个表时,所有孩子都在经常总是与父母同时检索。在这种情况下,通过父PK对子表进行聚类将减少检索子项时读取的页数。例如:
CREATE TABLE Invoice
(
-- Use the default MS Approach on the parent, viz Clustered by Surrogate PK
InvoiceID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
-- Index Fields here
);
CREATE TABLE InvoiceLineItem
(
-- Own Surrogate Key
InvoiceLineItemID INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED,
InvoiceID INT NOT NULL FOREIGN KEY REFERENCES Invoice(InvoiceID),
-- Line Item Fields Here
);
-- But Cluster on the Parent FK
CREATE CLUSTERED INDEX CL_InvoiceLineItem ON InvoiceLineItem(InvoiceID);
NonClustered Indexes
不,不要在没有仔细考虑的情况下包含列 - 索引树需要尽可能地缩小。索引列的排序很关键,并始终确保索引的设计考虑了selectivity - 您需要很好地理解数据的分布,以便选择最佳索引。
您可以考虑使用covering indexes包含(最多,几个)列,否则在调整性能关键查询时,需要从非聚簇索引中将书签查找回到表中。
答案 2 :(得分:1)
作为我使用的一个非常基本的经验法则,当返回少量数据时使用非聚簇索引,当查询返回更大的结果集时使用聚簇索引。
我建议你阅读Clustered Index Design Guidelines
对于索引视图:索引视图与索引表的工作方式相同。它可以提高性能,但是像索引表一样,它也会减慢速度。
我建议你阅读Improving Performance with SQL Server 2008 Indexed Views
在归类时,索引我发现越少越好。您需要研究您的数据,而不仅仅是在翻转时使用slap索引。检查链接的内容,添加索引并检查执行计划。有时你认为可以使一个好的指数实际上可以使事情变得更慢。
答案 3 :(得分:0)
使用SchemaBinding查看
...
毫无意义?或者我错过了这一点?
(更准确地说,索引视图,schemabinding是一种在这里结束的方法,其余的文本更多地讨论索引视图)
创建索引视图可能有(至少)两个原因。如果没有看到您的数据库,就无法确定哪些原因适用。
第一种是计算从基表计算的昂贵的中间结果。为了从该计算中受益,您需要确保查询使用索引。要使用索引,您需要查询视图并指定NOEXPAND
,或使用Enterprise或Developer Edition(在Ent / Dev版本上,即使基表也可以使用索引被查询并且没有提到视图
第二个原因是通过实施例如,以更简单的方式强制执行不可强制执行的约束。对视图的unique
约束,这可能会在基表上强制执行某种形式的条件唯一性。
第二个示例 - 假设您希望表T能够包含具有相同U
值的多个行 - 但是这些行中只有一个可以标记为Default
。在筛选索引可用之前,这通常实现为:
CREATE VIEW DRI_T_OneDefault
WITH SCHEMABINDING
AS
SELECT U
FROM S.T
WHERE Default = 1
GO
CREATE UNIQUE CLUSTERED INDEX IX_DRI_T_OneDefault on DRI_T_OneDefault (U)
重点是这些索引强制执行约束。在这种情况下,每个实际使用索引的查询是否无关紧要。同样,任何唯一约束都可以在基表上声明,但从未在任何查询中实际使用过。