2010-06-11 4 views
-2

J'ai 4 tables mysql et ai une seule requête avec JOIN sur plusieurs tables et je le demande via jquery ajax, mais cela prend beaucoup trop de temps, d'environ 1-3 minutes pendant que je vouloir les exécuter en moyenne 2 à 5 secondes.comment puis-je exécuter de grandes requêtes mysql rapide

Existe-t-il un moyen spécial d'exécuter les requêtes rapidement?

+3

Veuillez ajouter quelques informations supplémentaires telles que les requêtes/requêtes exactes que vous utilisez; le code Ajax et PHP; ce que vous faites et quel est exactement le goulot d'étranglement qui le rend si lent. –

+1

les requêtes s'exécutent généralement rapidement ... êtes-vous sûr que le problème est dans la requête? ... peut-être que vous faites quelque chose après la requête qui le rend lent ... – Reigel

+0

s'il y avait un moyen spécial de faire la requête rapide , je suis sûr que le SGBD aurait déjà fait cette manière spéciale comme la manière standard :) –

Répondre

5

Il existe différentes façons d'optimiser les requêtes.

  1. Vérifiez vos index
  2. Faire 1 grande requête ins't toujours plus rapide que faire quelques petits (vérifier les performances de chaque)

Une question plus détaillée avec l'échantillon SQL serait utile que bien.

+0

SELECT DISTINCT * FROM messages s JOINT budy f ON s.userid = f.fid ET s.time> = f.f_since OU s.userid = '$ thisid' O WH f.myid = '$ thisid 'GROUP BY s.pid DESC LIMIT 20 Voici ma requête et j'obtiens seulement les résultats ou les messages inclus –

+0

Je serais également méfiant des requêtes qui utilisent DISTINCT. Cela a des utilisations valables, mais est souvent utilisé comme une béquille pour les mauvaises données ou la structure. En fait, le groupe par les garanties de discutabilité ... – blissapp

2

Avec les jointures, l'opération principale qui accélère les choses crée un index sur les champs de la clause ON.

2
SELECT 
    DISTINCT * 
FROM 
    posts s 
JOIN 
    budy f ON s.userid = f.fid AND s.time >= f.f_since OR s.userid='$thisid' 
WHERE 
    f.myid='$thisid' 
GROUP BY 
    s.pid DESC 
LIMIT 20 

En regardant votre requête, je pense que votre JOIN est le coupable. Je n'ai jamais vu de syntaxe de jointure avec des conditions booléennes attachées, donc je ne suis pas exactement sûr de la façon dont il va se comporter sans le tester directement sur mysql.

pensées évidentes:

  • est posts.userid indexé?
  • est f.fid indexé?
  • qu'en est-il de posts.time et de budy.f_since?
  • vos options AND et OR sur l'instruction de jointure nécessitent-elles des parenthèses?

Avez-vous essayé de réécrire la requête pour voir si votre temps peut être amélioré? Peut-être que cela pourrait faire une différence:

SELECT 
    DISTINCT * 
FROM 
    posts s 
JOIN 
    budy f ON s.userid = f.fid 
WHERE 
    s.userid='$thisid' 
    s.time >= f.f_since 
GROUP BY 
    s.pid DESC 
LIMIT 20 

Puisque je ne suis pas sûr de ce que les données sont dans vos tables et ce que vous attendez de voir la suite de vos jointures, je ne peux pas être sûr que ma requête correspondre à la vôtre. Vous devez d'abord les vérifier. Aussi, n'oubliez pas d'utiliser la commande EXPLAIN pour savoir ce que mysql veut faire avec votre requête.

1

Sans voir le schéma, la taille de la ligne, le nombre de lignes dans la base de données, et les mêmes statistiques pour typique interroge son impossible d'indiquer où vous allez mal . Contrairement à pdwalker, j'ai vu des expressions conditionnelles dans les instructions de jointure, et je ne sais toujours pas ce que votre requête est destinée à faire. Je soupçonne que c'est soit un morceau de code très intelligent ou un très bête.

99% du temps, ces problèmes peuvent être résolus en réglant vos requêtes/schémas. Pour les autres 1%, vous devez regarder votre infrastructure - par ex. avoir un cluster de base de données (même s'il est maître/esclave) au lieu d'un seul nœud.

C.

2

J'ai trouvé que la façon dont vous écrivez la requête peut faire la différence entre un temps d'exécution d'heures ou de jours jusqu'à 5 millisecondes (résultat réel sur une base de données TRÈS grande). Certaines des choses que j'ai faites ont été d'apprendre à lire les résultats EXPLAIN (c'est l'outil le plus précieux pour comprendre comment MySQL comprend votre requête) en utilisant des sous-requêtes au lieu des jointures, en spécifiant un indice DB n'utilise pas la bonne, en ajoutant des index combinés (primary, column_1, column_2) et en ajoutant "straight_join" pour forcer la base de données à rejoindre les tables dans l'ordre que vous avez spécifié.

+0

Tous les très bons points, Robbie + 1 – Mawg

2

D'abord, utilisez EXPLAIN pour trouver le (s) goulot (s) d'étranglement! EXPLAIN vous indique les détails sur la façon dont la requête est exécutée. Cela devrait toujours être votre premier point de départ lors de l'optimisation des requêtes (ajouter des index, réécrire la requête et ainsi de suite ...).

http://dev.mysql.com/doc/refman/5.1/de/explain.html

2

Pour répondre à votre question réelle. Non. Il n'y a pas de manière spéciale de faire des requêtes rapides. Nous n'utilisons pas tous le paramètre secret "FAST" et rions lorsque vous vous battez avec des requêtes plus lentes.