【问题标题】:Is there a speed difference in ordering by int vs. float?按 int 与 float 排序是否存在速度差异?
【发布时间】:2011-11-13 17:16:50
【问题描述】:

在数据库中检索条目时,在 SELECT 语句中使用 ORDERBY 时,将值存储为浮点数或小数与 int 有区别吗?

【问题讨论】:

    标签: performance database-design sql-order-by


    【解决方案1】:

    这取决于。您没有指定 RDBMS,所以我只能专门与 SQL Server 交谈,但数据类型具有与之相关的不同存储成本。 Ints 的范围是 1 到 8 个字节,Decimals 是 5-17,floats 是 4 到 8 个字节。

    RDBMS 将需要从磁盘读取数据页以查找您的数据(最坏的情况),并且它们只能在 8k 数据页上容纳这么多行。因此,如果您有 17 字节小数,那么每次读取从磁盘读取的行数将是您正确调整数据大小并使用具有 1 字节成本的 tinyint 存储 X 时的 1/17。

    当您对数据进行排序(排序)时,该存储成本将产生级联效应。它会尝试在内存中排序,但如果你有无数行并且内存不足,它可能会转储到临时存储中进行排序,并且你一遍又一遍地支付这笔费用。

    索引可能会有所帮助,因为数据可以按排序方式存储,但同样,如果将数据放入内存中对于肥胖的数据类型可能效率不高。

    [编辑]

    @Bohemian 对整数与浮点比较的 CPU 效率做了一个很好的说明,但在数据库服务器上 CPU 出现峰值的情况非常罕见。您更有可能受到磁盘 IO 子系统和内存的限制,这就是为什么我的答案侧重于将数据输入引擎以执行排序操作与比较 CPU 成本之间的速度差异。

    【讨论】:

    • 谢谢,@billinkc。数据库很可能是 PostgreSQL。我可能需要一个 bigint 以便在保存记录以稍后按特定顺序排序时具有更大的灵活性。
    【解决方案2】:

    (已编辑)由于intfloat 在磁盘上占用完全相同的空间,当然在内存中——即32 位——唯一的区别在于它们的处理方式处理 .

    int 应该比float 排序更快,因为比较更简单:处理器可以在一个机器周期内比较整数,但浮点数的位必须在比较之前“解释”以获得值(不确定多少个周期,但可能不止一个,尽管某些 CPU 可能特别支持浮点比较)。

    【讨论】:

    • 关于实际 CPU 成本的好点,我关注的是磁盘和内存
    • 我同意,但对于小数,它不应该是真的:它们的编码方式有点像旧的 EBCEDIC,应该在二进制模式下快速比较。
    • 看起来它完全取决于处理器的实现:有些具有浮点单元,这使得它们非常快。但是 +1 因为 int 在所有情况下仍然保证很快。
    • 虽然你说的是正确的,但它也明显不完整,因为在大多数情况下,你没有指出几个额外的 CPU 周期是多么无关紧要。 IOW :您没有指出,对于几个额外的 CPU 周期来产生显着的差异,您需要数百万次比较,需要比较数千行,如果您是在 那种 场景中,与此类卷的磁盘 IO 所需的典型时间相比,您可能从 CPU 消耗中获得的任何“显着”差异通常仍然几乎没有。
    • @Erwin Smou - 抱歉,我没有为您说明我指出的区别是 only 区别,因为这两种类型在磁盘上占用完全相同的空间并在内存中 - 32 位。我以为我很好地回答了这个问题。我已经编辑了答案,明确说明了什么是常识。
    【解决方案3】:

    一般来说,数据类型的选择应该由数据类型是否适合存储需要存储的值来决定。如果给定的数据类型不合适,那么它的效率就无关紧要。

    就磁盘 i/o 而言,速度差异是二阶的。在您的设计就一阶效应而言良好之前,不要担心二阶效应。

    当可以按排序顺序检索查询时,正确的索引设计将大大减少延迟。但是,加快查询的速度是以减慢其他进程为代价的,例如修改索引数据的进程。必须考虑权衡,看看是否值得。

    简而言之,在担心会增加 10% 到磁盘 i/o 的东西之前,先担心会使磁盘 i/o 翻倍或更糟的东西

    【讨论】:

    • 关于设计的要点,沃尔特。我问这个问题的真正原因是因为我想在数据库中构建一个相对时间线stackoverflow.com/questions/7342264,并且想知道我是否应该只使用 bigint 或 float 来对事件进行排序。毕竟,如果我在 int 上创建记录时将数字分开,我可以通过取中间的数字在 2 个旧事件之间插入一个新事件。我也可以使用小数,因为我总是可以在末尾添加一个新位置以插入 (.50 --> .501 --> .51) 之间。
    猜你喜欢
    • 2017-02-06
    • 2010-10-14
    • 1970-01-01
    • 2012-05-27
    • 2015-04-19
    • 2012-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多