6
votes

Une simple requête mysql prise pour toujours (plus de 20 minutes!)

Peut-être que vous pouvez m'aider. Je dois interroger 3 tables afin d'obtenir des données pour un stock financier.

L'idée est d'aller à la table des instruments, de trouver l'index de chaque instrument, puis d'apporter tous les prix de cet instrument en particulier avec les indicateurs que sont sur une table séparée. p>

Tables Stockdata ​​code> et indicateurs code> sont presque 50.000 enregistrements. instruments code> seulement 30. p>

Ceci est la requête qui ne fonctionne pas: p> xxx pré>

voici le résultat expliqué p >

TABLE `indicators` (
  `id`             int AUTO_INCREMENT NOT NULL,<br>
  `instrument_id`  int,
  `date`           date,
  `sma_5`          float(10,3),
  `sma_14`         float(10,3),
  `ema_14`         float(10,3),
  /* Keys */
  PRIMARY KEY (`id`)
)

TABLE `instruments` (
  `id`         int AUTO_INCREMENT NOT NULL,
  `name`       char(20),
  `country`    char(50),
  `newsquery`  char(100),
  /* Keys */
  PRIMARY KEY (`id`)
)

TABLE `stockdata` (
  `id`        int AUTO_INCREMENT NOT NULL,
  `name`      char(10),
  `date`      date,
  `open`      float,
  `high`      float,
  `low`       float,
  `close`     float,
  `volume`    int,
  `adjclose`  float,
  /* Keys */
  PRIMARY KEY (`id`)
)


5 commentaires

Pourquoi y a-t-il des parenthèses autour de la condition de jointure?


Combien de lignes sont dans chacune des tables impliquées?


Bonjour, table stockData et indicateurs sont presque 50.000 enregistrements. Instruments seulement 30.


Pouvez-vous poster un schéma de votre table?


Il serait amélioré si la table des instruments stocké l'ID de la table Stockdata au lieu du nom.


4 Réponses :


1
votes
select ind.ddate, ins.name, ind.sma_14, ind.sma_5, 
     (select close from stockdata where name = ins.name limit 1) as close
from indicators ind
join instruments ins on ind.instrument_id = ins.instrument_id

1 commentaires

Bonjour, la deuxième option a fonctionné comme suit Sélection des indicateurs. date , instruments.name, indicateurs.sma_14, indicateurs.sma_5, (Sélectionnez la fermeture de stockData où Name = Instruments.Name Limite 1) Comme proche des indicateurs Indicateurs Rejoignez Instruments Instruments sur les indicateurs.Instrument_id = Instruments.ID mais toujours pris: 44619 rangées extraites (29,42 secondes)



1
votes

Je me méfie de rejoindre le champ Stockdata.name. Avez-vous les bons index définis sur le champ Nom de la table Stockdata et Instruments? Est-il possible que la jointure sur le nom puisse renvoyer des résultats non valides et que vous pourriez vous joindre à un autre champ ?Id?


1 commentaires

La chose est que la table Stockdata n'a pas de colonne Instrument_id, c'est pourquoi j'ai besoin d'apporter la table d'instauration pour obtenir l'ID Intrument pour ce nom donné, puis rejoindre la table des indicateurs.



0
votes

Vous avez interrogé sur le nom de champ non indexé dans Stockdata. Créez un index ou rejoindre à la place ID. (Je ferais ce dernier, changeant le nom sur ID dans les instruments)


0 commentaires

5
votes

Vous rejoignez les indicateurs Tableau sur la table INSTRUMENTS TABLE, et les indicateurs .InStrument_ID Colonne n'est pas indexé.

Vous êtes Rejoindre également la table instruments sur la table stockdata à l'aide du instruments.name et stockdata.name colonnes, les deux qui sont de type char . Rejoindre en utilisant char ou varchar est généralement significativement plus lent que de se joindre à l'utilisation de colonnes int :

Utilisation des touches de charcuterie pour les jointures, combien est la surcharge?

Pour aggraver les choses, votre Char sont des tailles différentes ( char (20) et Char (10) respectivement), et ils ne sont pas indexés. Cela rend vraiment les choses difficiles pour MySQL! Voir Comment MySQL utilise des index pour plus d'informations. < / p>

Idéalement, vous devez modifier votre structure de table afin que la jointure puisse être effectuée à l'aide des champs indexés int . Quelque chose comme ceci: xxx

puis utilisez les champs indexés de votre jointure: xxx

en utilisant indexé int colonnes, vos jointures seront beaucoup plus rapides. Utiliser des contraintes d'innoDB aidera à assurer l'intégrité des données.

S'il y a une raison pour laquelle vous devez vous connecter à la colonne nom , rendez la même taille et indexez-les.


0 commentaires