2017-02-27 5 views
3

J'ai une table avec le champ qui est action_time clé primaire et le type est datetimepartitionnement de MySQL ne fonctionne pas

J'essaie de le casser sur les partitions

ALTER TABLE foo PARTITION BY RANGE (MONTH(action_time)) 
(
PARTITION p01 VALUES LESS THAN (02) , 
PARTITION p02 VALUES LESS THAN (03) , 
PARTITION p03 VALUES LESS THAN (04) , 
PARTITION p04 VALUES LESS THAN (05) , 
PARTITION p05 VALUES LESS THAN (06) , 
PARTITION p06 VALUES LESS THAN (07) , 
PARTITION p07 VALUES LESS THAN (08) , 
PARTITION p08 VALUES LESS THAN (09) , 
PARTITION p09 VALUES LESS THAN (10) , 
PARTITION p10 VALUES LESS THAN (11) , 
PARTITION p11 VALUES LESS THAN (12) , 
PARTITION p12 VALUES LESS THAN (13) , 
PARTITION pmaxval VALUES LESS THAN MAXVALUE 
); 

dans phpmyadmin je vois des partitions avec des lignes mais quand j'exécute

explain partitions select * from foo where action_time between '2017-01-01 20:34:08' and '2017-01-21 20:34:08'; 

ou

explain partitions select * from foo where action_time > '2017-01-01 20:34:08' && action_time < '2017-01-21 20:34:08' 

elle frappe toutes les partitions (P01, P02, P03, P04, P05, P06, P07, P08, P09, P10, P11, P12, pmaxval)

ce que je fais mal?

J'essaie aussi de cette façon le même résultat

ALTER TABLE foo 
    PARTITION BY RANGE( YEAR(action_time)) 
    SUBPARTITION BY HASH(MONTH(action_time)) 
    SUBPARTITIONS 12 (
    PARTITION p2015 VALUES LESS THAN (2016), 
    PARTITION p2016 VALUES LESS THAN (2017), 
    PARTITION p2017 VALUES LESS THAN (2018), 
    PARTITION p2018 VALUES LESS THAN (2019), 
    PARTITION p2019 VALUES LESS THAN (2020), 
    PARTITION p2020 VALUES LESS THAN (2021), 
    PARTITION p2021 VALUES LESS THAN (2022), 
    PARTITION p2022 VALUES LESS THAN (2023), 
    PARTITION p2023 VALUES LESS THAN (2024), 
    PARTITION p2024 VALUES LESS THAN (2025), 
    PARTITION p2025 VALUES LESS THAN (2026), 
    PARTITION p2026 VALUES LESS THAN (2027), 
    PARTITION p2027 VALUES LESS THAN (2028), 
    PARTITION p2028 VALUES LESS THAN (2029), 
    PARTITION p2029 VALUES LESS THAN (2030), 
    PARTITION pmax VALUES LESS THAN MAXVALUE 
); 

J'ai besoin de briser la table par année et par mois pour améliorer le temps de sélection, quand je sélectionne entre les dates qu'il sholdn't recherche dans tablée il devrait chercher dans les partitions pertinentes. Comment puis-je faire ceci?

Répondre

1

Vous avez trouvé une autre raison pour laquelle PARTITIONing est pratiquement inutile.

Supposé que vous aviez spécifié BETWEEN '2015-11-05' AND '2017-02-02'. Quelles partitions aurait-il besoin de frapper? Tous.

Supposé que vous aviez spécifié BETWEEN '2015-11-05' AND '2016-02-02'. Quelles partitions aurait-il besoin de frapper? 4, mais il n'est pas assez intelligent pour envelopper. Donc ça va (je pense) tout frapper.

Il existe un nombre limité de modèles (MONTH() ne fait pas partie de ceux-ci) où le partitionnement sera "correct". Pour faire BY RANGE(some date), vous êtes limité à BY RANGE(TO_DAYS(date)) (et quelques autres) Mais alors vous devez créer une nouvelle partition tous les mois (ou plus souvent). Et, facultativement, DROP la partition la plus ancienne.

Maintenant, pour une autre raison, pourquoi vous prévoyez est probablement inutile. Quel avantage vous attendez-vous à obtenir du partitionnement? Peut-être la performance? Probablement ne vous donnera aucun avantage de performance. Voyons vos requêtes pour que je puisse expliquer pourquoi.

Un simple

SELECT ... 
    WHERE date >= '...' 
     AND date < '...' + INTERVAL 20 DAY 

fonctionnera aussi vite avec INDEX(date) comme avec le partitionnement. Peut-être même plus vite. Si le WHERE contient autre chose, cela change tout.

My PARTITION blog

Pourquoi PARTITIONNEMENT ne pas accélérer les requêtes simples

Disons que vous avez un SELECT simple qui a un indice très bon, comme vous spécifiez la valeur exacte du PRIMARY KEY. (Cela s'appelle une «requête ponctuelle».)

Cas 1: Table non partitionnée. Les index utilisent une structure BTree. Pour localiser un enregistrement spécifique sur un million de lignes, il est nécessaire de forer le BTree, qui aura environ 3 niveaux de profondeur. Pour un milliard de lignes, il peut s'agir de 5 niveaux.

Cas 2: Table cloisonnée. Le partitionnement divise la table en plusieurs tables, chacune ayant des index. Pour localiser une ligne spécifique, vous devez d'abord localiser la partition particulière (sous-table), puis explorer la zone BTower la moins profonde pour cette partition. Pensez si cela supprime (peut-être) un niveau du BTree, mais en ajoutant l'effort supplémentaire d'atteindre la partition. La différence de performance est minuscule. Et il n'est pas clair si vous gagnez ou perdez. (Caching, structures de données, etc, rendent cette analyse complexe.)

Conclusion: Pour les requêtes ponctuelles, le partitionnement n'aide jamais, en supposant que vous ayez un index approprié sur l'équivalent non partitionné.

Votre requête particulière est une simple requête "gamme": WHERE action_time BETWEEN ... AND ...

La structure de la table optimale (y compris le partitionnement et l'indexation) est

  • Aucune partition
  • INDEX(action_time)

Une autre remarque: Si plusieurs partitions sont concernées, le SELECT récupérera des lignes (le cas échéant) h partition (après l'élagage), les mettre ensemble, puis pourrait devoir trier les résultats (en fonction d'autres clauses dans le SELECT). Hélas, il n'y a pas de parallélisme dans l'exécution de la requête, donc la variante partitionnée est plus impliquée, donc probablement plus lente.

+0

il y a d'autres règles comme type = '...' et m_id = '...' cette table est énorme et elle est remplie avec beaucoup d'enregistrements quotidiens Je pensais que le partitionnement accélèrent sélectionnez – David

+0

Et, avec votre nouvelle édition, vous avez trouvé un exemple de pourquoi je dis que «SUBPARTITION» est inutile. –

+0

J'ai ajouté "Pourquoi le PARTITIONNEMENT n'accélère pas les requêtes simples" à ma réponse. –