6
votes

Un moyen le plus efficace de trouver l'entier le plus proche de MySQL?

J'ai une table dans une base de données MySQL à partir duquel je souhaite sélectionner la ligne avec l'horodatage le plus proche à un autre horodatage donné.

TIME CODE> est la colonne TIMESTAMP (un horodatage INTEGER UNIX). J'ai choisi 1250710000 code> arbitrairement. P>

C'est la requête que j'ai proposée, et je me demande s'il y a un moyen plus efficace de le faire: p>

SELECT *, ABS(time - 1250710000) AS time_dist FROM table
 ORDER BY time_dist ASC LIMIT 1


0 commentaires

3 Réponses :


1
votes

Comme Evan dit, comme vous l'avez bien. Je recommanderais un index sur ce champ d'horodatage afin que MySQL puisse scanner l'index plus petit plutôt que toute la table. En outre, j'essaierais une "boxe" pour voir si l'index peut accélérer les choses: XXX

Les limites ci-dessus pour interroger environ +/- 1 jour. Vous devrez faire des points de repère pour voir si l'analyse d'index supplémentaire (la clause OLS) est plus rapide que l'informatique ABS () sur toutes les entrées de la table.


1 commentaires

Je n'aime pas avoir des limites arbitraires comme ça.



1
votes

serait-il plus efficace de sélectionner le temps minimum plus grand et le maximum Temps qui est plus petit puis juste des abdominaux ces deux. Cela devrait éviter de devoir fonctionner sur le Table entière.

Sélectionnez max (heure) comme prev où l'heure <1250710000;

Sélectionnez Min (heure) comme suivant où l'heure> 1250710000;

Sélectionnez Min (ABS (prev), ABS (Suivant));

Mon SQL n'est pas assez fort pour les combiner en un, et la surcharge de trois Les requêtes peuvent tuer des économies, mais cela pourrait être possible.


0 commentaires

10
votes

En supposant que temps est indexé, vous pouvez obtenir le prochain record presque gratuitement: xxx

et si je ne me trompe pas , la même chose devrait s'appliquer à l'enregistrement précédent, MySQL vient de lire l'index dans l'ordre inverse. Utilisez une union des deux, commandez-les par date diff et voila! Le résultat ressemblera à ce xxx

idéalement, au lieu de > et << / code> vous devez utiliser > => => et <= et excluez l'enregistrement de référence à l'aide de son identifiant principal, pour tenir compte des enregistrements partageant le même horodatage.


2 commentaires

Super idée, mais l'horodatage de référence ( 1250710000 dans ce cas n'est pas dans la même table. Cela dit, je suppose que cette requête est à peu près la même en termes d'efficacité?


@Cyouung: Cette requête n'est pas la même en termes d'efficacité. Votre requête fait un ABS (Time - 125071000) ON Chaque rangée . Tant que vous avez un index sur heure , cette requête ne lira jamais plus de deux rangées.