Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

Préface

Récemment, la société avait un point de vue différent sur la question de l'utilisation de la fonction DATE_FORMAT lors de la révision du code. Le DATE_FORMAT spécifique affectera-t-il l'index? Dans quelles circonstances cela aura-t-il un impact? Rien ne s'est passé ce week-end, une vague de tests à travers le plan d'exécution de mysql.

Utiliser l'analyse d'explication

Le plan d'exécution est de montrer comment Mysql exécute une instruction SQL, en utilisant EXPLAIN. La sortie inclut la séquence des requêtes SQL, s'il faut utiliser l'index et les informations d'index utilisées, comme illustré dans la figure

Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

id: indique l'ordre de la table d'opération de sélection dans la requête, exécutée dans l'ordre du plus grand au séquentiel

select_type : Ceci représente le type de sélection, les valeurs facultatives sont: SIMPLE (simple)

Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

type : cet attribut représente le type d'accès et il existe de nombreux types d'accès. Les plus courants sont les suivants: ALL (scan complet de la table), index (scan d'index), range (scan de plage), ref (scan d'index non unique), eq_ref (scan d'index unique), (const) constant reference, La vitesse d'accès est de lente à rapide. Parmi eux: range (range) est commun avec entre et…, supérieur et inférieur à ce cas. Conseil: Vous pouvez vérifier si le SQL lent est indexé ou non, et quel index est parti, peut être vérifié via cette propriété.

Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

table: représente la table interrogée par l'instruction

possible_keys: comme son nom l'indique, cet attribut donne l'instruction de requête, l'index qui peut être pris, (comme le nom de l'index sur certains champs). Le fourni ici n'est qu'une référence, pas l'index réel, ce qui entraînera que possible_Keys ne soit pas Null, la clé est le phénomène vide.

key : affiche les index réellement utilisés par MySQL, y compris l'index de clé primaire (PRIMARY) ou le nom de l'index auto-construit.

key_len: indique le nombre d'octets utilisés par l'index,

ref: condition de correspondance de connexion, si l'index de clé primaire est pris, la valeur est: const, pour l'analyse complète de la table, il s'agit d'une valeur nulle

lignes: le nombre de lignes à analyser, c'est-à-dire le nombre de lignes à analyser pour obtenir le nombre de lignes cible, qui est généralement supérieur au nombre de lignes renvoyées. Dans des circonstances normales, plus les lignes sont petites, plus l'efficacité est élevée, et la plupart des optimisations SQL réduisent la taille de cette valeur. (Remarque: idéalement, le nombre de lignes numérisées est théoriquement le même que le nombre réel de lignes renvoyées, mais cette situation est extrêmement petite, comme les requêtes associées, le nombre de lignes numérisées sera considérablement augmenté par rapport au nombre de lignes renvoyées)

Extra : cet attribut est très important. Cet attribut comprend des informations sur la situation réelle lors de l'exécution de SQL. Comme ce qui précède, le "using where" est utilisé, ce qui signifie la valeur obtenue en filtrant avec where. Les plus couramment utilisés sont: "Using temporaire": Use Table temporaire "using filesort": utiliser le tri de fichiers

Instruction de table et insertion de données SQL comme indiqué:

Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

S'il y a un partenaire qui a besoin d'une vérification, attachez également SQL, ce qui est cohérent avec l'image ci-dessus:

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `birth_date` date NULL DEFAULT NULL,
  `is_delete` tinyint(1) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `name`(`name`) USING BTREE,
  INDEX `age`(`age`) USING BTREE,
  INDEX `birth_date`(`birth_date`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '小明1', 1, '2000-01-01', 0);
INSERT INTO `user` VALUES (2, '小明2', 2, '2001-01-02', 0);
INSERT INTO `user` VALUES (3, '小明3', 3, '2002-01-03', 0);
INSERT INTO `user` VALUES (4, '小明4', 4, '2003-01-04', 0);
INSERT INTO `user` VALUES (5, '小明5', 5, '2004-01-05', 0);
INSERT INTO `user` VALUES (6, '小明6', 6, '2005-01-06', 0);
INSERT INTO `user` VALUES (7, '小明7', 7, '2006-01-07', 0);
INSERT INTO `user` VALUES (8, '小明8', 8, '2007-01-08', 0);
INSERT INTO `user` VALUES (9, '小明9', 9, '2008-01-09', 0);
INSERT INTO `user` VALUES (10, '小明1', 10, '2009-01-10', 0);
INSERT INTO `user` VALUES (11, '小明11', 11, '2010-01-11', 0);
INSERT INTO `user` VALUES (12, '小明12', 12, '2011-01-12', 0);
INSERT INTO `user` VALUES (13, '小明13', 13, '2012-01-13', 0);
INSERT INTO `user` VALUES (14, '小明14', 14, '2013-01-14', 0);
INSERT INTO `user` VALUES (15, '小明15', 15, '2014-01-15', 0);
INSERT INTO `user` VALUES (16, '小明16', 16, '2015-01-16', 0);
INSERT INTO `user` VALUES (17, '小明17', 17, '2016-01-17', 0);
INSERT INTO `user` VALUES (18, '小明18', 18, '2017-01-18', 0);
INSERT INTO `user` VALUES (19, '小明19', 19, '2018-01-19', 0);
INSERT INTO `user` VALUES (20, '小明20', 20, '2019-01-20', 0);
INSERT INTO `user` VALUES (21, '小明21', 21, '2020-01-21', 0);

Processus de vérification

Remarque: la base de données utilisée dans cet article est mysql: 5.7.24.

1. Aucune fonction DATE_FORMAT

La première façon:

expliquer select * from user where date_naissance <= '2009-10-10';

Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

La clé peut être utilisée comme indiqué dans la figure ci-dessus: date_naissance.

La deuxième façon:

EXPLAIN SELECT * FROM USER WHERE date_naissance <= '2009-10-10' and birth_date> = '2009-10-10';

Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

La clé est utilisée comme indiqué dans la figure ci-dessus: date_naissance.

2. Utilisez la fonction DATE_FORMAT

La première façon:

EXPLAIN
SELECT
 *
FROM
 USER
WHERE
 birth_date >= DATE_FORMAT('2019-10-10', '%Y-%m-%d');

EXPLAIN
SELECT
 *
FROM
 USER
WHERE
 birth_date >= DATE_FORMAT('2019-10-10', '%Y-%m-%d')
AND birth_date <= DATE_FORMAT('2020-12-10', '%Y-%m-%d');

Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

La deuxième façon:

EXPLAIN
SELECT
 *
FROM
 USER
WHERE
 DATE_FORMAT(birth_date, '%Y-%m-%d') >= '2019-10-10';

EXPLAIN
SELECT
 *
FROM
 USER
WHERE
 DATE_FORMAT(birth_date, '%Y-%m-%d') >= '2019-10-10'
AND DATE_FORMAT(birth_date, '%Y-%m-%d') <= '2020-12-10';

Ali: Le champ de condition est indexé, pourquoi la requête est-elle si lente?

Les deux groupes de SQL ci-dessus ont été testés en ajoutant DATE_FORMAT aux champs et aux paramètres. Les résultats sont indiqués dans la figure. L'index date_naissance n'est pas efficace,  principalement en fonction de la clé du champ .

Par conséquent, dans le processus de développement, vous devez éviter d'utiliser ce type de fonction, sinon cela peut entraîner une défaillance de l'index et une analyse complète de la table.

Pour résumer

Choisissez en fonction de la situation réelle :

①Utilisez la première méthode de DATE_FORMAT, utilisez DATE_FORMAT dans le paramètre de requête au lieu du champ de requête .

EXPLAIN
SELECT
 *
FROM
 USER
WHERE
 birth_date >= DATE_FORMAT('2019-10-10', '%Y-%m-%d')
AND birth_date <= DATE_FORMAT('2020-12-10', '%Y-%m-%d');

②N'utilisez pas la deuxième méthode dans DATE_FORMAT, interrogez en fonction de la plage, comme la requête un

-- 举例:
EXPLAIN SELECT
 *
FROM
 USER
WHERE
 create_time >= '2026-10-24 00:00:00'
AND create_time <= '2026-10-24 23:59:59';

Ecrire à la fin

Bienvenue à tous à faire attention à mon compte public [Le vent et les vagues sont aussi silencieux que le code ], un grand nombre d'articles liés à Java, du matériel didactique y seront mis à jour et les matériaux compilés y seront également placés.

Si vous pensez que l'écriture est bonne, aimez-la et ajoutez un suiveur! Faites attention, ne vous perdez pas, continuez à mettre à jour! ! !

Je suppose que tu aimes

Origine blog.51cto.com/14957073/2562904
conseillé
Classement