Есть ли разница в скорости сортировки по int и float?

Есть ли разница между сохранением значений в виде числа с плавающей запятой или десятичной дробью и целым числом при извлечении записей в базе данных при использовании ORDERBY в операторе SELECT?


person Matt Norris    schedule 09.09.2011    source источник


Ответы (3)


Это зависит. Вы не указали СУБД, поэтому я могу говорить только с SQL Server, но типы данных имеют разные затраты на хранение, связанные с ними. Ints варьируются от 1 до 8 байтов, Десятичные знаки: 5-17 и числа с плавающей запятой составляют от 4 до 8 байтов.

РСУБД потребуется читать страницы данных с диска, чтобы найти ваши данные (в худшем случае), и они могут вместить только такое количество строк на странице данных размером 8 КБ. Итак, если у вас 17-байтовые десятичные дроби, вы получите 1/17 от количества строк, считываемых с диска за одно чтение, чем вы могли бы получить, если бы вы правильно рассчитали размер данных и использовали tinyint со стоимостью 1 байт для хранения X.

Эта стоимость хранения будет иметь каскадный эффект, когда вы перейдете к сортировке (упорядочению) данных. Он попытается выполнить сортировку в памяти, но если у вас есть миллиард строк и вам не хватает памяти, он может сбросить во временное хранилище для сортировки, и вы снова и снова платите эту стоимость.

Индексы могут помочь, поскольку данные могут храниться в отсортированном виде, но опять же, если получение этих данных в памяти может быть не таким эффективным для типов данных с избыточным весом.

[редактировать]

@Bohemian делает тонкое замечание об эффективности ЦП при сравнении целочисленных значений и чисел с плавающей запятой, но на сервере базы данных загрузка ЦП происходит на удивление редко. Скорее всего, вы будете ограничены подсистемой ввода-вывода диска и памятью, поэтому мой ответ фокусируется на разнице в скорости между получением этих данных в движке, чтобы он выполнял операцию сортировки, по сравнению со стоимостью сравнения ЦП.

person billinkc    schedule 09.09.2011
comment
Спасибо, @billinkc. База данных, скорее всего, будет PostgreSQL. Мне, вероятно, понадобится bigint, чтобы у меня было больше гибкости при сохранении записей для последующей сортировки в определенном порядке. - person Matt Norris; 12.09.2011

(Отредактировано) Поскольку как int, так и float занимают точно такое же пространство на диске и, конечно же, в памяти - т.е. 32 бита - единственная разница заключается в том, как они выглядят обработано.

int должен быть быстрее сортировать, чем float, потому что сравнение проще: процессоры могут сравнивать целые числа за один машинный цикл, но биты с плавающей запятой должны быть «интерпретированы», чтобы получить значение перед сравнением (не уверен, сколько циклов, но, вероятно, больше чем один, хотя некоторые процессоры могут иметь специальную поддержку для сравнения с плавающей запятой).

person Bohemian♦    schedule 09.09.2011
comment
Хорошая точка зрения на фактическую стоимость процессора, я сосредоточился на диске и памяти. - person billinkc; 09.09.2011
comment
Я бы согласился, но для десятичных чисел это не должно быть правдой: они закодированы как-то как старый EBCEDIC и должны быстро сравниваться в двоичном режиме. - person Patrick Honorez; 09.09.2011
comment
Похоже, это полностью зависит от реализации процессора: у некоторых есть блоки с плавающей запятой, что делает их очень быстрыми. Однако +1, потому что ints по-прежнему гарантированно будут быстрыми во всех случаях. - person Klaim; 09.09.2011
comment
Хотя то, что вы говорите, верно, оно также явно неполно в том смысле, что вы не можете указать, насколько неуместны несколько дополнительных циклов ЦП в большинстве случаев. IOW: вы не указываете, что для того, чтобы несколько дополнительных циклов ЦП имели заметное различие, вам нужны миллионы и миллионы сравнений, то есть тысячи и тысячи строк для сравнения, и если вы в этом сценарии любая заметная разница, которую вы можете получить от потребления ЦП, обычно все равно будет почти нулевой по сравнению с типичным временем, необходимым для дискового ввода-вывода для таких томов. - person Erwin Smout; 09.09.2011
comment
@Erwin Smou - извините, я не объяснил вам, что указанная мною разница заключалась в единственной разнице, поскольку оба типа занимают одинаковое пространство на диске и в памяти - 32 бита. Я думал, что хорошо ответил на вопрос. Я отредактировал ответ, четко указав то, что общеизвестно. - person Bohemian♦; 10.09.2011

В общем, выбор типов данных должен определяться тем, подходит ли тип данных для хранения значений, которые необходимо сохранить. Если данный тип данных неадекватен, не имеет значения, насколько он эффективен.

С точки зрения дискового ввода-вывода разница в скорости второго порядка. Не беспокойтесь об эффектах второго порядка, пока ваш проект не будет хорош в отношении эффектов первого порядка.

Правильный дизайн индекса приведет к значительному сокращению задержек, когда запрос может быть получен в отсортированном порядке с самого начала. Однако ускорение этого запроса выполняется за счет замедления других процессов, например процессов, которые изменяют индексированные данные. Компромисс должен быть рассмотрен, чтобы увидеть, стоит ли оно того.

Короче говоря, беспокойтесь о вещах, которые могут удвоить ваш дисковый ввод-вывод или хуже, прежде чем беспокоиться о вещах, которые собираются добавить 10% к вашему диску ввода-вывода.

person Walter Mitty    schedule 09.09.2011
comment
Хороший замечание по поводу дизайна, Уолтер. Настоящая причина, по которой я задаю вопрос, заключается в том, что я хочу построить относительную временную шкалу stackoverflow.com/questions/7342264 в базе данных. и мне интересно, следует ли мне просто использовать bigint или float для сортировки событий. В конце концов, если я разделяю числа при создании записей в int, я могу вставить новое событие между двумя старыми событиями, взяв число на полпути между ними. Я также мог использовать десятичную дробь, так как всегда можно было просто добавить новое место в конце, чтобы вставить между ними (.50 - ›.501 -› .51). - person Matt Norris; 12.09.2011