0

假设一个数据库表存储了一些文件元数据。每个文件都可以通过一个全局唯一的文件 ID 来标识。每个文件都位于一个文件夹(可以存储多个文件)中,该文件夹也具有全局唯一 ID。因此,该表除其他列外,还有两个唯一标识符:

FileID (GUID/uniqueidentifier)
FolderID (GUID/uniqueidentifier)

请注意,FileID表中的每个都应该是不同的(分配了一个随机 GUID),而相同的FolderID可能会出现多次。要获取特定的文件记录,只能FileID使用:

SELECT * FROM table WHERE FileID=...

我的主要问题是:明确指定FolderIDFileID限制要搜索的记录数量是否有任何性能优势?像这样:

SELECT * FROM table WHERE FileID=... AND FolderID=...

应该使用哪种方式,第一种,第二种,有关系吗?它是否取决于某些条件,例如索引、字段基数等?SQL Server 在优化这样的查询方面有多聪明?条件的顺序是否相关(即WHERE FileID=... AND FolderID=...vs WHERE FolderID=... AND FileID=...)?表面上指定的唯一潜在好处FolderID似乎是对极不可能的FileIDGUID 冲突的一些保护。


我最初的猜测(不知道查询是如何在内部执行的)是这样的:如果我们忽略块大小并假设两个字段都被索引(假设 B 树或任何此类logN结构),那么在第一种情况下(仅使用FileID)搜索存储X文件时的时间复杂度为:log2(X)

如果 X 文件均匀分布在d个文件夹中,每个文件夹将包含f个文件,搜索复杂度变为:log2(d) + log2(f) = log2(d*f) = log(X)- 没有区别(加上现实生活中的一些潜在开销,但它不会影响复杂度本身)。这是假设FolderIDs首先搜索 ,然后是 的子集FileIDs。如果两个字段都没有被索引,那么也没有明显的区别。

然而,假设只有FileID被索引而不被索引(使用N/2FolderID平均复杂度的线性搜索) - 现在如果我们使用第二种形式的查询,搜索复杂度变得比只使用更糟糕- 例如当X = 100 万个文件分布在d = 50000 个文件夹中 - 意味着每个文件夹f = 20 个文件。d/2 + log2(f)FiledIDlog2(X)

SQL Server 会检测到这样的事情并采取相应的行动吗?

4

1 回答 1

2

您错过了 Index Seek
Scans 与 Seeks的强大功能

如果要优化 FolderID 的性能,请选择 FileID,然后将 FolderID、FileID 设置为集群 PK(并按此顺序)。
在选择中指定两者。
您将获得索引搜索。

或者只是将 FileID 设为 PK 并仅在 FileID 上搜索。
您将再次获得索引搜索。

如果 FileID 是 PK,那么如果您想单独加速对 FolderID 的搜索,则需要在 FolderID 上添加索引。
该 FolderID 索引将占用空间。
聚集索引不占用(额外的)空间,但你只得到一个。

索引查找非常快。

于 2013-06-27T14:17:02.847 回答