Je suis à court de ressources. J'ai une table avec environ 100K lignes. Lors de l'interrogation de cette table, les résultats sont généralement vifs, environ 2 ms ou plus. Mais chaque fois que j'utilise un ORDER BY, la performance chute comme une pierre à environ 120 ms. J'ai lu la page MySQL ORDER BY Optimization mais je ne peux pas dire que je comprends tout. Surtout les index ne sont pas clairs pour moi.Optimiser une requête ORDER BY
En fin de compte, je voudrais lancer la requête suivante:
SELECT *
FROM `affiliate_new_contracts`
WHERE phone_brand IN ('Apple','Blackberry','HTC','LG','Motorola','Nokia',
'Samsung','Sony Ericsson')
AND contract_length IN ('12','24')
AND (addon IS NULL OR addon IN('Telfort Sms 300','Surf & Mail'))
AND (plan_name = 'Telfort 100'
AND
credible_shop = 1
)
ORDER BY average_price_per_month ASC, phone_price_guestimate DESC,
contract_length ASC;
Mais je serais heureux si je compris les principes sous-jacents.
La suppression de la clause ORDER BY dans la requête précédente la fait fonctionner en 20ms au lieu de 120ms. J'ai un index sur le champ average_price_per_month
mais la simplification de la clause ORDER BY à ORDER BY average_price_per_month
n'a donné aucune augmentation de performance. Que je ne comprends pas. Je suis également dans le noir à propos de ce que l'on appelle les index multi-colonnes qui devraient être en mesure de m'aider avec la requête ultime.
Toute aide serait appréciée. Comment puis-je faire ce mauvais garçon? Ou est-ce utopique?
La syntaxe CREATE TABLE
est la suivante:
$ show create table affiliate_new_contracts;
CREATE TABLE `affiliate_new_contracts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`plan_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`contract_length` int(11) DEFAULT NULL,
`phone_brand` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`price` float DEFAULT NULL,
`average_price_per_month` float DEFAULT NULL,
`phone_price_guestimate` float DEFAULT NULL,
`credible_shop` tinyint(1) DEFAULT '0',
`addon` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`addon_price` float DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_affiliate_new_contracts_on_plan_name` (`plan_name`),
KEY `index_affiliate_new_contracts_on_average_price_per_month` (`average_price_per_month`),
KEY `index_affiliate_new_contracts_on_price` (`price`)
) ENGINE=InnoDB AUTO_INCREMENT=2472311 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
BTW Cette table est recréée par semaine et est pas mis à jour entre-temps.
J'ai reformaté la requête pour éviter les barres de défilement horizontales. Les deux derniers termes de requête (sur le nom du plan et le magasin crédible) sont écrits de manière incohérente avec le reste de la requête (les autres termes n'utilisent pas le nom de la table) et n'ont vraiment pas besoin de parenthèses. J'ai débattu de la possibilité de le réparer sans commenter ... et j'ai décidé de ne pas le faire. Si vous décidez de rendre ces termes cohérents, je vais supprimer ce commentaire. –
Excellent commentaire. Une partie de la requête est/a été générée (plus de preuves que je suis mal adapté aux requêtes). J'ai enlevé le nom de la table superflue. – harm