J'ai donc deux tables que je dois pouvoir obtenir des comptes pour. L'un d'eux détient le contenu et l'autre sur la relation entre elle et la table des catégories. Voici le DDL:
mysql> explain SELECT count(*) FROM content_page_categories USE INDEX (combo) I<br> NNER JOIN content_en USE INDEX (combo) ON (id = itemid) WHERE catid = 1 AND act<br> ive = 1 ; +----+-------------+-------------------------+-------+---------------+-------+---------+--------------------------+--------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------------------+-------+---------------+-------+---------+--------------------------+--------+--------------------------+ | 1 | SIMPLE | content_en | index | combo | combo | 6 | NULL | 125288 | Using where; Using index | | 1 | SIMPLE | content_page_categories | ref | combo | combo | 8 | const,mcms.content_en.id | 1 | Using where; Using index | +----+-------------+-------------------------+-------+---------------+-------+---------+--------------------------+--------+--------------------------+ 2 rows in set (0.00 sec)
5 Réponses :
Le problème est la colonne "Active" dans Content_en. Évidemment, si vous avez juste besoin de savoir combien de registres de contenu étaient liés à une catégorie particulière (active ou non), tout ce que vous aurez à faire est de:
SELECT count(1) FROM content_page_categories USE INDEX (combo) WHERE catid = 1 AND active = 1;
Il y a trop de dossiers à compter.
Si vous voulez une solution plus rapide, vous devrez stocker des données agrégées. P>
mysql ne prend pas en charge les vues matérialisées (ou vues indexées dans SQL Server Termes) Vous auriez donc besoin de les créer et de les maintenir vous-même. P>
Créer une table: p> puis remplissez-le: p> SELECT cnt
FROM page_active_category
WHERE active = 1
AND catid = 1
Je pense que la voie à suivre est désordonnée (code sage), c'est-à-dire les tables de synthèse. J'ai toujours détesté les tables de synthèse car elles ont tendance à augmenter le nombre de bogues dans l'application. La chose est, comme si j'étais énoncé dans ma question, j'ai essayé toutes les autres solutions - la proposition indiquée ici et a échoué. 200ms pour un décompte unique est inacceptable, les tables récapitulatives semblent être une route aller simple. Merci.
@MBOUCLAS: Dans SQL Server et Oracle, vous pouvez les avoir auto-remplis et automatiquement mis à jour, comme des index. MySQL a besoin d'une telle caractéristique aussi.
Pour moi avec vos données en tant que configuration, je recevais la requête de jointure de la prise de la requête ~ 50x fois plus longtemps que de simplement sélectionner à partir du contenu_page_categories.
J'ai pu obtenir des performances d'environ 10 fois plus lentement que de simplement choisir de la table des catégories en faisant Les éléments suivants avec vos données: p>
J'ai utilisé droit_join p> et la structure de table suivante (légèrement modifiée): p> and: p> Pour obtenir mieux que cela, je pense que vous aurez besoin d'une vue, une structure aplatie ou un autre type de champ de recherche (comme dans la gâchette pour peupler une rangée dans l'autre table comme indiquée par une autre affiche). P> EDIT: P> Je devrais également indiquer ce message décent sur pourquoi / quand faire attention avec < Code> droite_join code>:
Quand utiliser straight_join avec mysql p> si Vous l'utilisez, utilisez-le de manière responsable! p> p>
J'ai téléchargé vos données et j'ai essayé quelques expériences. Je couronne MySQL 5.6.12 sur une machine virtuelle Centos sur un MacBook Pro. Les temps que j'ai observés peuvent être utilisés à titre de comparaison, mais votre système peut avoir des performances différentes.
J'ai d'abord essayé sans les clauses d'index d'utilisation, car j'évite les remplissages d'optimisation dans la mesure du possible. Dans la plupart des cas, une simple requête comme celle-ci devrait utiliser l'index correct s'il est disponible. Codage rigide Le choix d'index dans une requête rend plus difficile l'utilisation d'un meilleur index plus tard. P>
J'utilise également des noms de corrélation (alias de table) pour rendre la requête plus claire. P>
mysql> CREATE TABLE page_active_category ( active INT NOT NULL, catid INT NOT NULL, cnt BIGINT NOT NULL, PRIMARY KEY (active, catid) ) ENGINE=InnoDB; mysql> INSERT INTO page_active_category SELECT e.active, c.catid, COUNT(*) FROM content_en AS e JOIN content_page_categories AS c ON c.itemid = e.id GROUP BY e.active, c.catid mysql> SELECT cnt FROM page_active_category WHERE active = 1 AND catid = 1
J'aimerais obtenir "en utilisant l'index" sur la deuxième table, donc j'ai besoin d'un index sur (actif, ID) dans cet ordre. J'ai dû utiliser l'index dans ce cas pour persuader l'optimiseur de ne pas utiliser la clé primaire. P>
mysql> ALTER TABLE content_page_categories ADD COLUMN active TINYINT(1);
mysql> UPDATE content_en JOIN content_page_categories ON id = itemid
SET content_page_categories.active = content_en.active;
mysql> ALTER TABLE content_page_categories ADD KEY combo3 (catid,active);
mysql> SELECT COUNT(*) FROM content_page_categories WHERE catid = 1 and active = 1;
Pour accélérer le comptage sur MySQL rejoint les sous-requêtes.
Par exemple, obtenir des villes avec placomount P>
ID Titre ...... p>
ID
city_id
Titre
..... p>
Essayez d'utiliser
SELECT Count (1) CODE> ouSELECT compte ('x') code>. Les deux peuvent être plus rapides queSELECT Count (*) CODE>.fait ça, aucun changement.Count (index) ne fait pas de diff.
Serait-il possible pour vous de poster la définition d'index s'il vous plaît?
Mieux appendez ces tentatives pour votre question. Ils sont très difficiles à lire comme un commentaire.
J'ai ajouté les définitions d'index
Pouvez-vous inclure la sortie de 'Desc' de votre requête?
Si vous vous référez à la description des champs et description, ils sont vides
Je pensais à la déclaration «Desc» comme synonyme de 'Expliquer': dev.mysql.com/doc/refman/5.0/fr/Unding-Explain.html
Explique ajoutée aussi
Vos scripts de données ne correspondent pas aux définitions de la table
@Quassnoi, juste tomber des colonnes
content_en.description code> etcontent_en.description_long code>.C'est la bonne façon de demander quelque chose. Nice et détaillé. +1