database - Sequential Guid 相对于标准 Guid 有哪些性能改进?

标签 database primary-key guid

<分区>

有人曾测量过在数据库中用作主键时顺序 Guid 与标准 Guid 的性能吗?


我不认为唯一 key 是可猜测的或不可猜测的,从 Web UI 或其他部分传递它们本身似乎是一种不好的做法,如果您有安全问题,我不认为如何使用guid 可以改进一些东西(如果这是问题,请使用框架的适当加密函数使用真正的随机数生成器)。
我的方法涵盖了其他项目,可以从代码生成顺序 guid,而无需数据库访问(即使仅适用于 Windows),并且它在时间和空间上都是独一无二的。
是的,提出问题的目的是回答它,为选择 Guids 作为其 PK 的人们提供一种改进数据库使用的方法(在我的例子中,允许客户在无需更改服务器的情况下承受更高的工作负载)。

似乎安全问题很多,在这种情况下,不要使用 Sequential Guid,或者更好的是,使用标准 Guid 用于从您的 UI 来回传递的 PK,并使用顺序 Guid 用于其他所有内容。一如既往,没有绝对的真理,我也编辑了主要答案以反射(reflect)这一点。

最佳答案

GUID 与顺序 GUID



一个典型的模式是使用 Guid 作为表的 PK,但是,正如其他讨论中提到的那样(参见 Advantages and disadvantages of GUID / UUID database keys) 有一些性能问题。

这是一个典型的Guid序列

f3818d69-2552-40b7-a403-01a6db4552f7
7ce31615-fafb-42c4-b317-40d21a6a3c60
94732fc7-768e-4cf2-9107-f0953f6795a5


这类数据的问题是:<
-

  • 值(value)观分布广泛
  • 几乎是随机的
  • 索引使用非常、非常、非常糟糕
  • 很多叶子在移动
  • 几乎每个 PK 都需要至少 在非聚集索引上
  • 问题发生在 Oracle 和 SQL Server



一种可能的解决方案是使用按如下方式生成的顺序 Guid:

cc6466f7-1066-11dd-acb6-005056c00008
cc6466f8-1066-11dd-acb6-005056c00008
cc6466f9-1066-11dd-acb6-005056c00008


如何从 C# 代码生成它们:

[DllImport("rpcrt4.dll", SetLastError = true)]
static extern int UuidCreateSequential(out Guid guid);

public static Guid SequentialGuid()
{
    const int RPC_S_OK = 0;
    Guid g;
    if (UuidCreateSequential(out g) != RPC_S_OK)
        return Guid.NewGuid();
    else
        return g;
}


好处

  • 更好地使用索引
  • 允许使用集群键(将 在 NLB 场景中验证)
  • 减少磁盘使用
  • 20-25% 的性能提升 最低成本



现实生活测量: 场景:

  • Guid 存储为 UniqueIdentifier SQL Server 上的类型
  • Guid 在 Oracle 上存储为 CHAR(36)
  • 大量插入操作,批处理 在一次交易中一起
  • 从 1 到 100 秒的插入取决于 在 table 上
  • 一些表 > 1000 万行



实验室测试 – SQL Server

VS2008 测试,10 个并发用户,无思考时间,叶表批量插入 600 次的基准测试过程
标准指南
平均。过程持续时间:10.5
平均。第二个要求:54.6
平均。响应。时间:0.26

顺序指南
平均。过程持续时间:4.6
平均。第二个要求:87.1
平均。响应。时间:0.12

Oracle 上的结果(抱歉,用于测试的工具不同)1.327.613 使用 Guid PK 在表上插入

标准向导0.02 秒。每次插入的运行时间,2.861 秒。 CPU 时间,总计 31.049 秒。过去

顺序引导0.00 秒。每次插入的运行时间,1.142 秒。 CPU 时间,总计 3.667 秒。过去

DB 文件顺序读取等待时间从 6.4 百万等待事件持续 62.415 秒变为 122 百万等待事件11.063 秒。

重要的是要看到所有的顺序 guid 都可以被猜到,所以如果安全是一个问题,那么使用它们并不是一个好主意,仍然使用标准 guid。
简而言之...如果您将 Guid 用作 PK,则每次它们不从 UI 来回传递时使用顺序 guid,它们将加快操作速度并且无需花费任何实现成本。

关于database - Sequential Guid 相对于标准 Guid 有哪些性能改进?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/170346/

相关文章:

php - 雅虎 YOS 社交 PHP5 库错误

C#:如何将包含空值的 guid 类型的数据库字段转换为局部变量?

mysql - 如何对 var length ids(复合字符串+数字)进行排序?

c# - 从 SQL Server 数据库中删除

Java:数据库连接。我的错误在哪里?

database - django uml 数据库

sql-server - Microsoft SQL Server 2008 主键的含义

python - 如何创建一个根据多种条件增加的ID?

c# - Guid 是值类型还是引用类型?

java - 在下拉列表中显示从数据库中选择的数据