2012-09-29 1 views
0

enter image description hereUne meilleure façon de stocker/interroger une arborescence spécifique dans SQL?

Nous avons obtenu ce modèle de données. Connaissant la profondeur d'arbre limitée, nos tables actuelles sont 1: 1 au modèle, avec des clés étrangères au nœud parent. Channel à Station, Measurement à Channel et Station. 90% des requêtes est:

select value from measurements where 
fk_station=X and fk_channel=Y and timestamp>=A and timestamp<=B 
order by timestamp asc 

Le reste 10% est similaire sur les autres tables horodatés, seulement plus simple en raison du manque fk_channel.

problème auquel nous sommes confrontés: il y a des centaines de millions de [station,channel,timestamp] uniques lignes Measurement table et de plus en plus. L'index d'horodatage était déjà si énorme et la clause d'ordonnancement si lente que nous devions commencer à la diviser par Station Id; nous avons donc les tables Measurement_<Station Id> et la clé étrangère Station est omise. Cela a beaucoup aidé, mais certaines tables ont quand même des dizaines de millions de lignes. Dans les pics de charge, nous avons environ 80000 requêtes/minute et les requêtes sur ces plus grandes tables sont remarquablement plus paresseuses. Nous courons toujours à partir d'une instance MySQL/ISAM sans aucun hacks d'optimisation. Environ 150 Go sur le système de fichiers.

  1. Y a-t-il une manière significativement différente/meilleure de stocker un tel modèle de données?
  2. Avec la structure actuelle, est-il normal que nous ayons ce genre de problèmes de performances avec cette taille/charge? La machine est la moyenne hw d'aujourd'hui, aucun atome incorporé ni bête de noyau 8+
  3. était la bonne chose à faire la division de Measurement table? Nous ne sommes pas des gourous SQL, mais la requête et l'index requis semblaient si évidents que nous n'avons même pas envisagé de l'optimiser. Le fractionnement a beaucoup aidé, mais quelque chose d'autre pourrait aussi y avoir
  4. Y at-il un autre moyen d'accélérer l'index? C'est un peu stupide que nous devons faire le même index en continuant à faire des sous-ensembles du même résultat. Nous n'utiliserons jamais aucune autre indexation, même pas le desc. C'est un appareil très spécialisé. Serait bien si l'index est en quelque sorte "ordre natif" :-)
  5. serait-il aider à distribuer/partitionner les tables divisées Measurement? Comme je l'ai dit, quelques tables sont encore énormes et le problème se sent à environ la taille de l'index dont la distribution ne va pas aider, alors peut-être tout simplement réduire la charge de requête ...

Répondre

1

Des règles simples à penser dans dbs relationnelles comme MySQL:

  1. Récupération trop de données est jamais rapide. L'agrégation peut être. - votre exemple de requête n'agrège rien. Je me demande si vous croquer et agréger ces valeur dans votre application. Astuce: Agréger en utilisant le moteur de magasin de colonnes par exemple. infinidb, il supporte aussi le parallélisme dans l'exécution des requêtes, mais pas innodb.
  2. Le tri d'une énorme quantité de données n'est jamais rapide - demandez-vous, si la requête renvoie des enregistrements de 100 Ko, combien consomme votre tâche/grille de travail crunching? Un utilisateur Web peut-il consommer 100 000 données à l'écran? Pas vraiment, alors LIMITEZ-le. De plus, trier par ID d'incrémentation automatique au lieu de l'horodatage. Les moteurs relationnels db ne sont pas bons pour trier des mandrins énormes de données, vous atteindrez bientôt le plafond.
+0

1. L'agrégation n'est pas une option, nous avons besoin de toutes ces données. La seule alternative serait d'implémenter une sorte de sous-échantillonnage dans une procédure stockée, ce qui est bien au-delà de ce que nous voulons jeter au problème. –

+0

2. La requête renvoie max de l'ordre de 10000 lignes. Tout est alimenté tel quel par le paquet graphique de frontend - qui fait la décimation mentionnée dans la puce 1. Mais je suis vraiment intéressé par le «tri par ID» - nous pouvons imaginer le post-tri au frontend. Cela signifie-t-il que nous n'aurons pas besoin de l'index même pour la sélection de la plage d'horodatage [A, B]? –

+0

"Les moteurs db relationnels ne sont pas bons pour trier d'énormes mandrins de données" des nouvelles surprenantes pour moi (SQL gourou je ne suis pas). Pouvez-vous m'indiquer une lecture éclairante à ce sujet? –

0

Est-il possible que le partage haut Les données de mesure sur plus d'une table peuvent réduire la taille? Si 90% des requêtes sont sur les dernières 24 heures d'horodatage, vous pouvez vouloir affiner ces données et stocker le reste dans une table séparée ou même dans une base de données. Je crois que la mesure devrait avoir un FK seulement pour Channel, qui a seulement son ID comme PK, et un FK à Station.

+0

Je n'ai pas dit que 90% sont limités aux X dernières heures :-) Tout à fait le contraire. Les requêtes très populaires sont comme "donne moi le mois en cours pour les années 2012-2009". –

Questions connexes