2012-05-06 2 views
1

Ma structure de table est la suivante:Table MySQL avec plus de 10 millions de lignes - comment accélérer la recherche en utilisant des index?

CREATE TABLE SINON EXISTE commodity_data (
dataid bigint (20) non signé NOT AUTO_INCREMENT NULL,
commodity smallint (6) NOT NULL,
market smallint (6) NOT NULL,
quantity flotteur NOT NULL,
price_min mediumint (9) NOT NULL,
price_max MEDIUMINT (9) NOT NULL,
price_modal MEDIUMINT (9) NOT NULL,
date Date NOT NULL,
horodatage modified NOT NULL CURRENT_TIMESTAMP DEFAULT ON UPDATE CURRENT_TIMESTAMP,
clé primaire (dataid)
) MOTEUR = InnoDB DEFAULT CHARSET = latin1 AUTO_INCREMENT = 7059415;

Mes SELECTs sur cette table where clauses avec un ou plusieurs des « produits de base », « marché » et « date » recherchés sur.

Mes commandes ORDER seront de price_min, price_max ou price_modal et parfois de la plupart des autres champs.

La table finira par être plus de 10 millions de lignes et continuera à augmenter d'environ 5 à 10 mille par jour.

Mon serveur est actuellement un double VPS 2.4Ghz xeon, 4 Go de RAM.

Le seul index est actuellement dans le champ 'dataid'. J'ai lu que la mise en place d'index peut aider et je pense que cela devrait être sur les produits, le marché et la date, mais je voulais vérifier si c'est juste avant d'aller de l'avant à moins qu'il y ait une meilleure façon de faire. La taille de la table sera d'environ 600 Mo et en croissance.

Les champs «marchandise» et «marché» renvoient à l'ID des marchandises et aux marchés dans d'autres tableaux. Je vais soit LEFT JOIN ou si c'est plus rapide, je vais lire ces tables dans des tableaux en PHP (simples tableaux associatifs à un niveau id => name). Il y a environ 300 produits et 2 000 marchés.

Actuellement, les opérations SELECT prennent trop de temps, et par exemple COUNT requêtes avec une clause WHERE prendra une minute ou plus.

Répondre

2

Si vous exécutez votre requête de sélection avec le EXPLAIN avant que le texte de la requête, MySQL affiche les informations de l'optimiseur sur le plan d'exécution de la requête, et les indices proposés qui accéléreront votre requête ...

+0

Quand je lance: SELECT * DE commodity_data OÙ marchandises IN (4, 8, 9) ET DATE ENTRE '2010-01-01' ET '2010-12-31' ORDER BY produit ASC, marché ASC, DATE ASC LIMIT 0, 30 Cela prend 25 secondes. Le EXPLIQUER donne les éléments suivants: id: 1 select_type: SIMPLE Table: commodity_data Type : ALL possible_keys: NULL clé: NULL key_len: NULL ref: NULL lignes: 7119981 supplémentaire: Utilisation où; Utilisation de filesort – N9ne

+0

Essayez de créer un index sur les champs de marchandise et de données ... – aleroot

1

Essayez de trouver les index compound dont vous avez besoin: si vous recherchez commodity ET market ET date, vous devriez avoir 1 (un) index sur les trois. Pour commander, si par exemple vous n'incluez pas market, l'ordre passera probablement à INDEX(commodity,date,market) (inutilisé en dernier). Si le WHERE varie énormément, plusieurs indices de composés pour les cas peuvent aider (par ex.INDEX(commodity,date,market) mais également INDEX(market,date,commodity). Gardez à l'esprit qu'ils sont un coup de performance lors de l'écriture/mise à jour.

Néanmoins, une minute est assez longue: assurez-vous que votre base de données peut charger la table en mémoire en définissant innodb_buffer_pool_sizeas high is it can go. Après cela, lancez le EXPLAIN mentionné sur les requêtes qui prennent encore beaucoup de temps et de prendre à partir de là.

+0

De quel volume de performance parlons-nous? Je vais entrer 5-10k lignes par jour dans un bloc. En fin de compte, je n'ai aucun problème avec INSERT prenant plus de temps (il n'y aura pas de mise à jour) tant qu'ils ne prennent pas beaucoup de multiples plus longtemps. – N9ne

+0

On me dit que l'augmentation de innodb_buffer_pool_size peut provoquer une corruption InnoDB en cas de panne d'un serveur et il est conseillé de ne pas l'augmenter. Il est actuellement défini sur 64M sur mon serveur. – N9ne

+0

5-10k par jour est à côté de rien, donc vous devriez être OK là. Innodb_buffer_pool_size ne provoque pas de corruption. Définir des valeurs inappropriées pour innodb_flush_log_at_trx_commit et puis arracher la puissance de votre serveur _might_ cause-le. Mais par tous les moyens, ne tenez pas compte du conseil de Peter Zaltsev dans le lien donné. Ce n'est pas comme s'il connaissait ses trucs MySQL ou quoi que ce soit [/ sarcasme]. – Wrikken

Questions connexes