


Intervieweur : Comment avez-vous interrogé 10 millions de données ?
Récemment, j'ai fait des simulations d'entretiens et d'optimisation de CV pour tout le monde, et j'ai découvert que beaucoup de gens s'affaiblissent lorsqu'ils voient des questions comme des dizaines de millions de données.
Peut-être que certaines personnes n'ont jamais rencontré de table contenant des dizaines de millions de données et ne savent pas ce qui se passera lors de l'interrogation de dizaines de millions de données.
Aujourd'hui, je vais vous faire réaliser un exercice pratique. Cette fois, il est basé sur MySQL 5.7.26 pour les tests
Préparation des données
Que faire si vous n'avez pas 10 millions de données. ?
Vous ne pouvez pas le créer vous-même sans données ?
Est-il difficile de créer des données ?
10 millions de création de code ?
C’est impossible, c’est trop lent, ça peut vraiment te prendre une journée entière pour courir. Vous pouvez utiliser des scripts de base de données pour une exécution beaucoup plus rapide.
Créer une table
CREATE TABLE `user_operation_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `ip` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `op_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr3` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr4` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr5` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr6` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr7` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr8` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr9` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr10` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr11` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `attr12` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
Créer un script de données
En utilisant l'insertion par lots, l'efficacité sera beaucoup plus rapide et tous les 1000 éléments seront validés si la quantité de données est trop importante, l'efficacité. de l'insertion par lots sera également lente
DELIMITER ;; CREATE PROCEDURE batch_insert_log() BEGIN DECLARE i INT DEFAULT 1; DECLARE userId INT DEFAULT 10000000; set @execSql = 'INSERT INTO `test`.`user_operation_log`(`user_id`, `ip`, `op_data`, `attr1`, `attr2`, `attr3`, `attr4`, `attr5`, `attr6`, `attr7`, `attr8`, `attr9`, `attr10`, `attr11`, `attr12`) VALUES'; set @execData = ''; WHILE i<=10000000 DO set @attr = "'测试很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的属性'"; set @execData = concat(@execData, "(", userId + i, ", '10.0.69.175', '用户登录操作'", ",", @attr, ",", @attr, ",", @attr, ",", @attr, ",", @attr, ",", @attr, ",", @attr, ",", @attr, ",", @attr, ",", @attr, ",", @attr, ",", @attr, ")"); if i % 1000 = 0 then set @stmtSql = concat(@execSql, @execData,";"); prepare stmt from @stmtSql; execute stmt; DEALLOCATE prepare stmt; commit; set @execData = ""; else set @execData = concat(@execData, ","); end if; SET i=i+1; END WHILE; END;; DELIMITER ;
Démarrez le test
La configuration de mon ordinateur est relativement faible : win10 pression standard i5, lecture et écriture d'environ 500 Mo de SSD
En raison de la faible configuration, seulement 3148000 éléments de données ont été préparés pour ce test, occupant 5 Go de disque (sans encore indexation) et exécuté pendant 38 minutes. Les étudiants ayant une bonne configuration informatique peuvent insérer plusieurs points de données pour les tests
SELECT count(1) FROM `user_operation_log`
Résultat renvoyé : 3148000
Trois. les temps de requête sont :
14060 ms 13755 ms 13447 ms
普通分页查询
MySQL 支持 LIMIT 语句来选取指定的条数数据, Oracle 可以使用 ROWNUM 来选取。
MySQL分页查询语法如下:
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
第一个参数指定第一个返回记录行的偏移量 第二个参数指定返回记录行的最大数目
下面我们开始测试查询结果:
SELECT * FROM `user_operation_log` LIMIT 10000, 10
查询3次时间分别为:
59 ms 49 ms 50 ms
这样看起来速度还行,不过是本地数据库,速度自然快点。
换个角度来测试
相同偏移量,不同数据量
SELECT * FROM `user_operation_log` LIMIT 10000, 10 SELECT * FROM `user_operation_log` LIMIT 10000, 100 SELECT * FROM `user_operation_log` LIMIT 10000, 1000 SELECT * FROM `user_operation_log` LIMIT 10000, 10000 SELECT * FROM `user_operation_log` LIMIT 10000, 100000 SELECT * FROM `user_operation_log` LIMIT 10000, 1000000
查询时间如下:
Quantité | Première fois | Deuxième fois | Troisième fois |
---|---|---|---|
10 articles | 53ms | 52ms | 47ms |
100 articles | 50ms | 60ms | 55ms |
1000 articles | 61ms | 74ms | 60ms |
10000 articles | 164ms | 180ms | 21 7ms |
100000 articles | 1609ms | 1741ms | 1764ms |
1000000 articles | 16219ms | 16889ms | 17081ms |
从上面结果可以得出结束:数据量越大,花费时间越长
相同数据量,不同偏移量
SELECT * FROM `user_operation_log` LIMIT 100, 100 SELECT * FROM `user_operation_log` LIMIT 1000, 100 SELECT * FROM `user_operation_log` LIMIT 10000, 100 SELECT * FROM `user_operation_log` LIMIT 100000, 100 SELECT * FROM `user_operation_log` LIMIT 1000000, 100
偏移量 | 第一次 | 第二次 | 第三次 |
---|---|---|---|
100 | 36ms | 40ms | 36ms |
1000 | 31ms | 38ms | 32ms |
10000 | 53ms | 48ms | 51ms |
100000 | 622ms | 576ms | 627ms |
1000000 | 4891ms | 5076ms | 4856ms |
从上面结果可以得出结束:偏移量越大,花费时间越长
SELECT * FROM `user_operation_log` LIMIT 100, 100 SELECT id, attr FROM `user_operation_log` LIMIT 100, 100
如何优化
既然我们经过上面一番的折腾,也得出了结论,针对上面两个问题:偏移大、数据量大,我们分别着手优化
优化偏移量大问题
采用子查询方式
我们可以先定位偏移位置的 id,然后再查询数据
SELECT * FROM `user_operation_log` LIMIT 1000000, 10 SELECT id FROM `user_operation_log` LIMIT 1000000, 1 SELECT * FROM `user_operation_log` WHERE id >= (SELECT id FROM `user_operation_log` LIMIT 1000000, 1) LIMIT 10
查询结果如下:
sql | 花费时间 |
---|---|
第一条 | 4818ms |
第二条(无索引情况下) | 4329ms |
第二条(有索引情况下) | 199ms |
第三条(无索引情况下) | 4319ms |
第三条(有索引情况下) | 201ms |
从上面结果得出结论:
第一条花费的时间最大,第三条比第一条稍微好点 子查询使用索引速度更快
缺点:只适用于id递增的情况
id非递增的情况可以使用以下写法,但这种缺点是分页查询只能放在子查询里面
注意:某些 mysql 版本不支持在 in 子句中使用 limit,所以采用了多个嵌套select
SELECT * FROM `user_operation_log` WHERE id IN (SELECT t.id FROM (SELECT id FROM `user_operation_log` LIMIT 1000000, 10) AS t)
采用 id 限定方式
这种方法要求更高些,id必须是连续递增,而且还得计算id的范围,然后使用 between,sql如下
SELECT * FROM `user_operation_log` WHERE id between 1000000 AND 1000100 LIMIT 100 SELECT * FROM `user_operation_log` WHERE id >= 1000000 LIMIT 100
查询结果如下:
sql | 花费时间 |
---|---|
第一条 | 22ms |
第二条 | 21ms |
从结果可以看出这种方式非常快
注意:这里的 LIMIT 是限制了条数,没有采用偏移量
优化数据量大问题
返回结果的数据量也会直接影响速度
SELECT * FROM `user_operation_log` LIMIT 1, 1000000 SELECT id FROM `user_operation_log` LIMIT 1, 1000000 SELECT id, user_id, ip, op_data, attr1, attr2, attr3, attr4, attr5, attr6, attr7, attr8, attr9, attr10, attr11, attr12 FROM `user_operation_log` LIMIT 1, 1000000
查询结果如下:
sql | 花费时间 |
---|---|
第一条 | 15676ms |
第二条 | 7298ms |
第三条 | 15960ms |
Les résultats montrent qu'en réduisant les colonnes inutiles, l'efficacité des requêtes peut également être considérablement améliorée.
Les vitesses de la première et de la troisième requête sont presque les mêmes. À ce stade, vous vous plaindrez certainement, alors pourquoi devrais-je. écrivez autant de champs ? , juste * et vous avez terminé
Notez que mon serveur et mon client MySQL sont sur la même machine, donc les données de requête sont similaires. Les étudiants qualifiés peuvent tester le client et MySQL séparément
SELECT *. Ça ne sent pas bon ?
Au fait, je voudrais ajouter ici pourquoi nous devrions interdire SELECT *
. N'est-ce pas délicieux parce que c'est simple et insensé ? SELECT *
。难道简单无脑,它不香吗?
主要两点:
用 " SELECT *
" 数据库需要解析更多的对象、字段、权限、属性等相关内容,在 SQL 语句复杂,硬解析较多的情况下,会对数据库造成沉重的负担。-
增大网络开销, Deux points principaux :*
SELECT *
" La base de données doit analyser plus d'objets, de champs, d'autorisations, d'attributs, etc. Contenu, lorsque les instructions SQL sont complexes et qu'il y a de nombreuses analyses difficiles, cela entraînera une lourde charge sur la base de données. *
Parfois, log, IconMD5 et autres sont inclus par erreur Inutile et volumineux champs de texte, la taille de la transmission des données augmentera de façon exponentielle. D'autant plus que MySQL et l'application ne sont pas sur la même machine, cette surcharge est très évidente. Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds











PHP est un langage de script largement utilisé du côté du serveur, particulièrement adapté au développement Web. 1.Php peut intégrer HTML, traiter les demandes et réponses HTTP et prend en charge une variété de bases de données. 2.PHP est utilisé pour générer du contenu Web dynamique, des données de formulaire de traitement, des bases de données d'accès, etc., avec un support communautaire solide et des ressources open source. 3. PHP est une langue interprétée, et le processus d'exécution comprend l'analyse lexicale, l'analyse grammaticale, la compilation et l'exécution. 4.PHP peut être combiné avec MySQL pour les applications avancées telles que les systèmes d'enregistrement des utilisateurs. 5. Lors du débogage de PHP, vous pouvez utiliser des fonctions telles que error_reportting () et var_dump (). 6. Optimiser le code PHP pour utiliser les mécanismes de mise en cache, optimiser les requêtes de base de données et utiliser des fonctions intégrées. 7

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

PHP et Python ont chacun leurs propres avantages, et le choix doit être basé sur les exigences du projet. 1.Php convient au développement Web, avec une syntaxe simple et une efficacité d'exécution élevée. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et des bibliothèques riches.

PHP convient au développement Web, en particulier dans le développement rapide et le traitement du contenu dynamique, mais n'est pas bon dans les applications de la science des données et de l'entreprise. Par rapport à Python, PHP présente plus d'avantages dans le développement Web, mais n'est pas aussi bon que Python dans le domaine de la science des données; Par rapport à Java, PHP fonctionne moins bien dans les applications au niveau de l'entreprise, mais est plus flexible dans le développement Web; Par rapport à JavaScript, PHP est plus concis dans le développement back-end, mais n'est pas aussi bon que JavaScript dans le développement frontal.

PHP et Python ont chacun leurs propres avantages et conviennent à différents scénarios. 1.PHP convient au développement Web et fournit des serveurs Web intégrés et des bibliothèques de fonctions riches. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et une bibliothèque standard puissante. Lors du choix, il doit être décidé en fonction des exigences du projet.

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

Les raisons pour lesquelles PHP est la pile technologique préférée pour de nombreux sites Web incluent sa facilité d'utilisation, son soutien communautaire solide et son utilisation généralisée. 1) Facile à apprendre et à utiliser, adapté aux débutants. 2) Avoir une énorme communauté de développeurs et des ressources riches. 3) Largement utilisé dans WordPress, Drupal et d'autres plateformes. 4) Intégrez étroitement aux serveurs Web pour simplifier le déploiement du développement.

PHP convient aux systèmes de développement Web et de gestion de contenu, et Python convient aux scripts de science des données, d'apprentissage automatique et d'automatisation. 1.Php fonctionne bien dans la création de sites Web et d'applications rapides et évolutifs et est couramment utilisé dans CMS tel que WordPress. 2. Python a permis de manière remarquable dans les domaines de la science des données et de l'apprentissage automatique, avec des bibliothèques riches telles que Numpy et Tensorflow.
