1
votes

MySQL: comment accélérer une requête en récupérant une grande quantité de données et en utilisant LIKE

J'ai une table de 3 666 058 enregistrements et 6 colonnes, définies comme suit:

CREATE TABLE IF NOT EXISTS `annoyance` (
    `a` varchar(50) NOT NULL default '',
    `b` varchar(50) NOT NULL default '',
    `c` longtext,
    `d` varchar(21) NOT NULL,
    `e` float default NULL,
    `f` smallint(6) NOT NULL default '0',
    KEY `ab` (`a`,`b`),
    KEY `b` (`b`),
    KEY `d` (`d`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

J'essaie de récupérer le contenu des colonnes a , b et d , lorsque a commence par un certain préfixe (3 lettres de long), soit aaa . Donc, j'exécute la requête suivante: SELECT a, b, c de l'ennui où un comme 'aaa%'; . Cela devrait récupérer environ 1 835 000 enregistrements de la table.

Mon problème est: cette requête est très lente (lorsqu'elle n'est pas mise en cache bien sûr), et prend parfois jusqu'à quelques minutes.

Alors, comment puis-je accélérer les choses pour cette requête particulière? Simething j'ai essayé mais sans succès est de créer un index sur un a (taille 3 ou sans spécifier de taille): MySQL ne prendrait même pas la peine d'utiliser l'index sauf si je le forcerais avec FORCE INDEX (indices d'index) et cela n'a pas semblé accélérer l'exécution de la requête.


1 commentaires

Je suggérerais de repenser l'ensemble de l'approche, en commençant par «pourquoi avez-vous besoin de récupérer rapidement 1,8 million de lignes?».


3 Réponses :


3
votes

Pour récupérer 1,8 million de lignes sur 3,6 millions, il faut essentiellement analyser la table entière. Vous ne pouvez pas faire grand-chose pour améliorer les performances.

Les index n'aideront pas. Si vous récupériez, disons 1000 lignes de la table, les index peuvent vous aider. Et, un index sur a serait utilisé pour le like . Vous pouvez également formuler ceci comme suit:

where a >= 'aaa' and a < 'aab'

Si vous vouliez que l'optimiseur choisisse encore plus facilement l'index.


0 commentaires

0
votes

Avez-vous essayé LEFT () Selon ce test, il est plus rapide que LIKE. http://cc.davelozinski.com/sql/ like-vs-substring-vs-leftright-vs-charindex

SELECT a,b,c from annoyance where LEFT(a,3) = 'aaa'


3 commentaires

LEFT ne permettra pas d’utiliser INDEX (a) . En règle générale: le masquage d'une colonne indexée dans une fonction empêche l'utilisation de cet index.


Cette référence n'est pas valide pour MySQL car elle fait référence à SQL Server.


En outre, cette référence vérifie les deux extrémités de la chaîne pour la sous-chaîne donnée; c'est plus complexe que ce que demande le PO.



0
votes

INDEX (a, b, d) (ou (a, d, b) ) s'exécuterait plus rapidement car ce serait un index "couvrant".

(Remplacez d par c si c est vraiment ce que vous cherchez.)


0 commentaires