8
votes

SQL - Requête accélère

J'utilise actuellement la requête suivante qui prend environ 8 minutes pour renvoyer le résultat en raison du volume de données (environ 14 mois). Y a-t-il une façon de pouvoir accélérer cela s'il vous plaît?

La base de données en question est MySQL avec Innodb Moteur P>

select
    CUSTOMER as CUST,
    SUM(IF(PAGE_TYPE = 'C',PAGE_TYPE_COUNT,0)) AS TOTAL_C,
    SUM(IF(PAGE_TYPE = 'D',PAGE_TYPE_COUNT,0)) AS TOTAL_D
from
        PAGE_HITS
where
    EVE_DATE >= '2016-01-01' and EVE_DATE <= '2016-01-05'
    and SITE =  'P'
    and SITE_SERV like 'serv1X%'
group by
    CUST


12 commentaires

Pouvez-vous spécifier quels index sont utilisés (le cas échéant) et aussi à quoi ressemblent les structures? Les clés primaires utilisées etc.?


Pourriez-vous fournir plus de détails: rangées de numéro, index, moteur de stockage et etc.


Merci beaucoup. Désolé j'ai manqué de mettre à jour ces détails. Laisse moi faire ça maintenant.


Les pls incluent également les résultats de l'explication.


Utilisez la requête existante comme sélection interne et déplacez-vous Site_Servime comme 'Serv1x%' à la requête extérieure.


Je viens de mettre à jour la question avec la structure de stockage de données pour répondre aux commentaires ci-dessus.


Sans Expliquer de la requête SELECT , ce sera très difficile (sinon impossible) à raconter quelles parties pourraient être améliorées.


Bien. Je vais devoir attendre pour avoir accès à l'accès qu'il explique. Je reviendrai ici une fois que j'y suis arrivé. En attendant, si je réussis à résoudre, je vais certainement informer ce forum.


Votre table est partitionnée? Pouvez-vous montrer la clause de partition s'il vous plaît?


Bonjour Thorsten - Merci d'avoir sauté. Les données sont partitionnées par Eve_Date. Chaque partition est de 6 mois de données. 14 mois de données sont répartis sur 3 partitions avec la dernière des partitions contenant 2 mois de données et de la croissance à la date. Ai-je répondu à la requête ou suis-je lointain? S'il vous plaît faites le moi savoir


Ah, ok donc ist par eve_date ... partition P0 valeurs moins que ... et non par mois (Eve_Date) (qui aurait été deux partitions uniquement inconscientes de la année). Merci pour la clarification.


Si vous avez une clé d'incrément automatique, les clés doivent être dans le même ordre avec les dates. Pourquoi n'essayez-vous pas d'aller chercher les résultats entre les clés qui se trouvent à la plage de dates? par exemple. ID entre (Sélectionnez le top 1 ID de page_hits où Eve_Date> = '2016-01-01' Commande par ID ASC) et (sélectionnez le top 1 ID de page_hits où eve_date <= '2016-01-05' commander par ID Desc)


4 Réponses :


2
votes

Le principal facteur d'optimisation serait index. On devrait correspondre aussi près que possible de votre requête, par exemple:

EVE_DATE, SITE, CUST, SITE_SERV


4 commentaires

Merci précuk. Je suis heureux de supprimer si , comment pourrais-je calculer la somme conditionnelle de manière efficace? Pourriez-vous s'il vous plaît aider ici?


Je dirais juste simplement sélectionner page_type, somme (page_type_count) comme total et gérer le cas "C" ou "D" dans votre application frontale; Mais comme je dis que ça ne vaut probablement pas la peine. Corrigé quelques fautes de frappe, ma phrase n'a eu aucun sens


Merci précuk. Je vais utiliser cette suggestion ailleurs dans mon développement. En ce qui concerne cette question, j'ai besoin de traiter les données INT EH DB Layer :(


Eh bien, si vous ne pouvez pas sauter le si, il suffit de les garder :) Vérifiez si vous avez un index avec Eve_Date, Site, Cust and Site_Serv et si vous pouvez essayer de mettre ce schéma sur un dB, vous pouvez exécuter expliquer sur, c'est tout ce que je peux recommander.



3
votes

Je n'ai pas les données, je ne peux donc pas tester la vitesse de ceci, mais je pense que ce serait plus rapide. XXX

Cela fonctionnait simplement sur mon violon sur MySQL 5.6 < / p>


2 commentaires

Bonne truc, je vais certainement essayer cela pour simplifier certaines questions que j'ai; Performance-sage, vous avez-vous une métrique?


Merci Merci Xpy. Cela a l'air génial. Je vais sûrement utiliser cela ailleurs. n Mon cas, il n'y a pas d'amélioration de la perfection. C'est un vrai bien que



2
votes

D'accord, comme la cloison de la gamme de table est sur Eve_Date, le SGBD doit facilement voir la partition à lire. Il s'agit donc de savoir quel index à utiliser.

Il y a une colonne que vous vérifiez pour l'égalité ( site = 'p' ). Cela devrait venir d'abord dans votre index. Vous pouvez ensuite ajouter eve_date et site_serveur dans n'importe quel ordre, je suppose. Ainsi, votre index devrait être capable de localiser les enregistrements de table en question aussi vite que possible.

Si, toutefois, vous ajoutez les autres champs utilisés dans votre requête à votre index, la table n'aurait même pas à Soyez lu, car toutes les données seraient disponibles dans l'index lui-même: xxx

Ceci devrait être l'index optimal de votre requête si je ne me trompe pas.


1 commentaires

Merci beaucoup Thorsten. Cette performance améliorée par une certaine mesure.



2
votes

ajoutez ces deux index: xxx

L'optimiseur examinera les statistiques et choisira entre eux. À peu près, le premier serait mieux s'il y a moins de lignes avec des "P" et des dates de cette gamme que "P" et "P" & "Serv1x%".

Oui, l'index "couvrant" que Thorsten pourrait Sois mieux, mais il a plus de champs que j'aime mettre dans un index.

partitionnement pourrait aide. Mais il y a trop de petites informations pour dire à coup sûr. Le partitionnement de la raison pourrait vous aider est que vous disposez d'une recherche "2 dimensions" - une plage de date et "Serv1x%". Vous auriez besoin de partitionner à la date ou à SITE_SERV, puis à avoir la touche principale (site, ..., ...) avec l'autre (date ou site_service) comme deuxième colonne. Les autres colonnes devraient inclure à la fois la clé de partition et une colonne pour la rendre unique. Cela devient si désordonné que je ne veux pas le penser.


0 commentaires