11
votes

Y a-t-il une différence de vitesse dans la commande par int contre float?

Lors de la récupération des entrées dans une base de données, y a-t-il une différence entre stocker des valeurs comme un flotteur ou une décimale contre un int lors de l'utilisation de Orderby dans une instruction SELECT?


0 commentaires

3 Réponses :


8
votes

(édité) depuis int et float occupe exactement le même espace sur le disque et bien sûr en mémoire - c'est-à-dire 32 bits - les seules différences sont de la manière dont ils sont traité .

int devrait être plus rapide de sorte que float , car la comparaison est plus simple: les processeurs peuvent comparer des intenses dans un cycle de la machine, mais les bits d'un flotteur doivent être "interprétés "Pour avoir une valeur avant de comparer (pas sûr du nombre de cycles, mais probablement plus d'un, bien que certains processeurs puissent avoir un soutien spécial pour la comparaison de flotteurs).


5 commentaires

Bon point sur le coût de la CPU réel, je me suis concentré sur le disque et la mémoire


Je serais d'accord, mais pour les décimales, cela ne devrait pas être vrai: ils sont codés d'une manière ou d'une autre comme ancienne euros et devraient comparer rapidement en mode binaire.


On dirait que cela dépend totalement de la mise en œuvre du processeur: certains ont des unités de points flottants qui les rendent très rapides. Cependant +1 car les INT sont toujours garantis pour être rapides dans tous les cas.


Bien que ce que vous dites est correct, il est également flagramment incomplet, dans le sens où vous ne sotez pas de savoir comment certains cycles de processeurs supplémentaires sont non pertinents, dans la plupart des cas. IOW: Vous ne parusez pas à souligner que pour quelques cycles de processeur supplémentaires pour faire une différence notable , vous avez besoin de millions et de millions de comparaisons, de milliers de dollars et de milliers de lignes à comparer, et si vous êtes Dans Ce scénario alors quelle que soit la différence "notable" que vous pourriez obtenir de la consommation de la CPU ne sera généralement presque presque rien, comparé au temps typique nécessaire au disque IO pour ces volumes.


@Erwin Smou - Désolé, je n'ai pas épelé pour vous que la différence que j'ai signalé était la différence , car les deux types occupent exactement le même espace sur disque et en mémoire - 32 bits. Je pensais avoir répondu à la question bien. J'ai édité la réponse à l'état explicitement, quelle est la connaissance commune.



8
votes

Cela dépend. Vous n'avez pas spécifié le RDBMS afin que je puisse uniquement parler à SQL Server spécifiquement, mais les types de données ont des coûts de stockage différents associés à eux. Ints gamme de 1 à 8 octets, Les décimales sont 5-17 et Les flotteurs sont de 4 à 8 octets.

Le RDBMS devra lire des pages de données hors disque pour rechercher vos données (pires cas) et ne peuvent qu'elles ne peuvent s'adapter à de nombreuses lignes sur une page 8K de données. Donc, si vous avez 17 décimales d'octets, vous allez avoir 1 / 17th de la quantité de lignes Lecture du disque de lecture par lecture que si vous auriez pu être si vous avez la taille de vos données correctement et que vous avez utilisé un tinyint avec un coût d'octet pour stocker X.

Ce coût de stockage aura un effet en cascade lorsque vous allez trier (commander par) vos données. Il tentera de trier la mémoire, mais si vous avez une bazillion des lignes et que vous êtes affamé pour la mémoire, il peut dépouiller le stockage de Temp pour le tri et que vous payez ce coût et plus.

Les index peuvent aider, car les données peuvent être stockées de manière triée, mais si la mémoire en mémoire peut ne pas être aussi efficace pour les types de données obèses.

[modifier]

@bohemian fait un point fine sur l'efficacité de la CPU des comparaisons entier entier VS flottant, mais elle est incroyablement rare que la CPU soit épinée sur un serveur de base de données. Vous êtes beaucoup plus susceptible d'être contraint par le sous-système et la mémoire du disque IO, c'est pourquoi ma réponse se concentre sur la différence de vitesse entre l'obtention de cette donnée dans le moteur pour effectuer la solution de tri du coût de comparaison de la CPU.


1 commentaires

Merci, @billinkc. La base de données sera probablement PostgreSQL. J'aurais probablement besoin d'un Bigint Donc, j'ai plus de flexibilité lors de la sauvegarde des enregistrements à trier plus tard dans un ordre particulier.



2
votes

En général, le choix des types de données devrait être motivé si le type de données est approprié pour stocker les valeurs requises pour être stockées. Si un type de données donné est inadéquat, cela n'a pas d'importance à quel point c'est efficace.

En termes d'E / S de disque, la différence de vitesse est le deuxième ordre. Ne vous inquiétez pas des effets secondaires avant que votre conception soit bonne en ce qui concerne les effets de premier ordre.

La conception d'index correcte entraînera une diminution énorme des délais lorsqu'une requête peut être récupérée dans l'ordre trié pour commencer. Cependant, accélérer cette requête est effectuée au prix de ralentissement d'autres processus, comme les processus qui modifient les données indexées. Le compromis doit être considéré comme voir s'il en vaut la peine.

En bref, souciez des choses qui vont doubler votre disque I / O ou pire avant de vous inquiéter des choses qui vont ajouter 10% à votre disque I / O


1 commentaires

Bon point sur le design, Walter. La véritable raison pour laquelle je pose la question est que je souhaite construire une chronologie relative Stackoverflow.com/questions/7342264 dans la base de données Et je me demande si je devrais simplement utiliser un Bigint ou un flotteur pour trier les événements. Après tout, si j'accumule les chiffres de séparation lors de la création des enregistrements sur un INT, je peux insérer un nouvel événement entre 2 anciens événements en prenant le numéro à mi-parcours entre les deux. Je pourrais également utiliser une décimale, car je pouvais toujours simplement ajouter un nouvel endroit à la fin pour insérer entre (.50 -> .501 -> .51).