MySQL高效查询实战:从基础语法到性能优化的核心手册
1. 项目概述为什么你需要一份自己的MySQL语句手册干了这么多年后端开发数据库操作是绕不过去的坎。无论是处理用户数据、生成报表还是做系统间的数据同步SQL语句就是程序员和数据库沟通的“普通话”。我见过太多同事包括刚入行时的我自己遇到一个稍微复杂点的查询需求第一反应就是去搜索引擎里找“MySQL 如何多表联查”、“MySQL 分组排序取第一条”。网上的答案五花八门质量参差不齐有时候照着抄还会因为版本差异报错白白浪费大量调试时间。所以我萌生了一个想法为什么不整理一份属于自己的、经过实战检验的MySQL基本语句手册呢这份手册的目的不是替代官方文档而是作为一个“速查急救包”。它应该包含那些你真正高频使用、容易忘记语法细节、但网上答案又常常误导人的语句。它的内容应该源于实际项目中的需求经过生产环境的验证并且附带清晰的场景说明和避坑指南。当你面对一个具体的数据操作问题时能在这份手册里快速定位到模式相似的语句稍作修改就能用上这才是它的核心价值。本手册将围绕“查找”这一核心操作展开因为数据检索是绝大多数应用的起点也是最考验SQL功底的部分。2. 手册设计思路从“能用”到“高效好用”的进化一份好的手册不应该只是命令的罗列。我设计这份手册的思路遵循了从基础到进阶从功能实现到性能优化的路径。2.1 核心原则场景驱动而非语法驱动我不会按照“SELECT, INSERT, UPDATE, DELETE”这样的语法分类来组织内容。因为在实际开发中你面临的是一个具体的业务问题比如“找出上个月消费金额最高的前十名用户及其订单详情”。这个问题背后涉及的是多表连接JOIN、聚合函数SUM、MAX、分组GROUP BY、排序ORDER BY和结果限制LIMIT的复合操作。因此手册的内容组织将以典型业务场景为线索将相关的语法点串联起来讲解。2.2 内容分层适应不同阶段的开发者手册内容分为三个层次基础操作层涵盖单表的增删改查CRUD这是所有操作的基石。重点在于语法的准确性和完整性例如INSERT时如何优雅地处理可能存在的重复键。复杂查询层聚焦多表关联查询、子查询、各种类型的JOIN、以及分组聚合。这一层是解决复杂业务逻辑的关键会重点讲解不同写法的性能差异和适用场景。性能与技巧层介绍如何利用索引、执行计划EXPLAIN来分析和优化查询。这一部分会将前两层的语句与数据库性能知识结合起来让你写的SQL不仅结果正确而且执行高效。2.3 强调“为什么”对于每一个关键语句或写法手册都会解释“为什么这么写”。例如为什么在WHERE条件中对字段使用函数会导致索引失效为什么有时候EXISTS比IN的性能更好理解背后的原理才能举一反三而不是死记硬背。3. 核心语句解析与实操要点这一部分我们将深入最常用的“查找”SELECT语句拆解其各个组成部分并附上必须注意的细节。3.1 SELECT语句骨架比你想象的要复杂一个完整的SELECT语句其子句的执行顺序不是书写顺序至关重要它直接决定了查询的逻辑和性能。书写顺序是SELECT - FROM - WHERE - GROUP BY - HAVING - ORDER BY - LIMIT。但数据库引擎的理解顺序是FROM - WHERE - GROUP BY - HAVING - SELECT - ORDER BY - LIMIT。理解这个顺序就能明白很多问题。比如为什么不能在WHERE子句中使用SELECT中定义的别名因为WHERE执行时SELECT子句的字段计算包括别名定义还没发生。反过来为什么可以在ORDER BY中使用别名因为ORDER BY在SELECT之后执行。3.2 WHERE子句过滤的艺术WHERE子句是过滤数据的闸门。这里有几个极易出错和影响性能的点运算符优先级AND的优先级高于OR。当混合使用时务必使用括号()来明确逻辑。WHERE condition1 OR condition2 AND condition3和WHERE (condition1 OR condition2) AND condition3结果是天壤之别。NULL值处理NULL与任何值包括NULL本身的比较结果都是NULL即假。判断是否为NULL必须使用IS NULL或IS NOT NULL使用 NULL会永远得不到结果。这是一个非常高频的错误。LIKE模糊查询与索引LIKE ‘%关键字%’这种前后都加通配符的写法是无法使用普通B-Tree索引的会导致全表扫描。如果需求是前缀匹配尽量写成LIKE ‘关键字%’这样是可以利用索引的。对于全文搜索应考虑使用MySQL的全文索引FULLTEXT或专业的搜索引擎。注意在WHERE条件中避免对字段进行函数操作或计算如WHERE YEAR(create_time) 2023或WHERE amount * 1.1 100。这会导致引擎无法使用该字段上的索引。应改为WHERE create_time ‘2023-01-01’ AND create_time ‘2024-01-01’和WHERE amount 100 / 1.1。3.3 JOIN连接关系型数据库的精髓多表连接是SQL强大能力的体现但也是复杂度和性能问题的来源。INNER JOIN内连接最常用的连接返回两个表中连接字段匹配的行。关键是要清楚连接条件ON子句。如果连接条件写错可能导致结果集遗漏或膨胀。LEFT/RIGHT JOIN左/右外连接以左表或右表为基准返回所有行即使另一表中没有匹配。另一表无匹配的字段用NULL填充。常用于“查询所有用户及其可能存在的订单”这类场景。关于“笛卡尔积”如果忘记写JOIN条件或者连接条件永远为真就会产生笛卡尔积即两表所有行的组合。这会导致结果集行数急剧膨胀表A行数 * 表B行数极易耗尽内存或使数据库崩溃。务必检查每个JOIN都配有合理的ON条件。实操心得在写复杂的多表JOIN时我习惯先用注释把业务逻辑描述清楚然后一步步构建SQL。先写FROM和JOIN部分确保表之间的连接关系正确再写WHERE条件进行过滤最后再写SELECT字段避免过早关注字段而忽略了整体逻辑。4. 高级查询场景实现详解掌握了基础语法后我们来看几个高级且实用的查询场景。这些场景的解决方案往往能直接应用到你的项目中。4.1 分组聚合与组内排序经典“Top N”问题业务场景找出每个部门department_id工资salary最高的前3名员工。 这是一个非常经典的“分组内排序取前N”问题。在MySQL 8.0之前需要用到变量技巧写法晦涩。而MySQL 8.0引入的窗口函数让这个需求变得异常简单。-- MySQL 8.0 推荐写法 SELECT * FROM ( SELECT employee_id, name, department_id, salary, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) as salary_rank FROM employees ) ranked_employees WHERE salary_rank 3;这里使用了ROW_NUMBER()窗口函数它会在每个部门PARTITION BY department_id内按工资降序ORDER BY salary DESC生成一个唯一的排名。然后外层查询只需过滤出排名小于等于3的记录即可。除了ROW_NUMBER还有RANK和DENSE_RANK区别在于处理并列排名的方式根据业务需求选择。4.2 递归查询处理树形或层级数据业务场景查询某个员工的所有下级在组织架构树中。 在MySQL 8.0之前处理无限层级的树形数据非常麻烦通常需要在应用层递归或使用特殊的存储设计如路径枚举、嵌套集。MySQL 8.0引入了公共表表达式CTE和递归CTE完美解决了这个问题。-- MySQL 8.0 递归查询示例 WITH RECURSIVE subordinate_tree AS ( -- 锚点部分先找到指定的上级员工 SELECT employee_id, name, manager_id FROM employees WHERE employee_id 1001 -- 假设要查找ID为1001的员工的所有下级 UNION ALL -- 递归部分不断查找下级 SELECT e.employee_id, e.name, e.manager_id FROM employees e INNER JOIN subordinate_tree st ON e.manager_id st.employee_id ) SELECT * FROM subordinate_tree;这个查询会从员工ID 1001开始递归地找到所有直接和间接向他汇报的员工。递归CTE是处理菜单、分类、组织架构等层级数据的利器。4.3 使用EXISTS优化IN子查询当子查询返回的结果集很大时使用IN可能会导致性能问题。因为数据库需要先执行子查询生成一个完整的结果列表然后再用主查询的字段去这个列表中逐个匹配。这时可以尝试改用EXISTS。-- 查找有订单的用户 -- 使用 IN SELECT * FROM users WHERE user_id IN (SELECT DISTINCT user_id FROM orders); -- 使用 EXISTS (通常更优) SELECT * FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id u.user_id);EXISTS是一个半连接semi-join它只关心子查询是否至少返回一行而不关心具体返回什么数据。数据库优化器通常能以更高效的方式如使用连接来执行EXISTS查询。但这不是绝对的具体哪种写法更好需要结合表的数据量、索引情况用EXPLAIN命令来查看执行计划。5. 性能排查与优化技巧实录写出能返回正确结果的SQL只是第一步写出能高效返回结果的SQL才是高手。这里分享几个我踩过坑才学会的优化技巧。5.1 必杀技读懂EXPLAIN执行计划EXPLAIN是你的SQL性能诊断仪。在任何一个SELECT语句前加上EXPLAIN关键字MySQL就会告诉你它打算如何执行这条语句。EXPLAIN SELECT * FROM orders o JOIN users u ON o.user_id u.user_id WHERE u.country ‘CN’;执行结果中的几个关键字段type访问类型从好到坏大致是system const eq_ref ref range index ALL。要尽量避免ALL全表扫描和index全索引扫描但需回表。key实际使用的索引。如果为NULL说明没用到索引。rowsMySQL估计需要扫描的行数。这个值越小越好。Extra额外信息。如果出现Using filesort文件排序无法利用索引排序或Using temporary使用了临时表通常意味着查询需要优化。5.2 索引失效的常见陷阱即使你建立了索引查询也可能用不上。除了前面提到的对字段进行函数运算还有隐式类型转换如果字段是字符串类型如VARCHAR但查询条件写成了数字WHERE user_id 123456MySQL会进行隐式类型转换导致索引失效。应确保类型一致WHERE user_id ‘123456’。使用OR连接非索引字段WHERE indexed_column ‘A’ OR non_indexed_column ‘B’。这种情况下优化器可能选择全表扫描。可以考虑拆分成两个查询用UNION或者为non_indexed_column也建立索引。不符合最左前缀原则对于复合索引INDEX(a, b, c)查询条件必须包含最左边的列a才能有效使用这个索引。WHERE b1或WHERE b1 AND c2是无法使用该索引的。5.3 分页查询深翻页的性能问题一个常见的性能杀手是LIMIT 100000, 20这种深翻页查询。MySQL需要先读取100020行数据然后丢弃前100000行只返回最后20行效率极低。优化方案-- 低效写法 SELECT * FROM articles ORDER BY create_time DESC LIMIT 100000, 20; -- 优化写法使用“书签”记录上一页最后一条的位置 SELECT * FROM articles WHERE create_time ‘上一页最后一条记录的时间’ -- 或使用ID ORDER BY create_time DESC LIMIT 20;这种优化要求你的排序字段通常是时间或自增ID是连续的并且查询条件能利用这个字段进行过滤。在UI设计上可以改为“加载更多”模式避免传统的页码跳转。5.4 避免SELECT *在业务代码中尤其是联表查询时养成只查询所需字段的习惯。SELECT *会带来几个问题增加网络传输开销尤其是包含TEXT/BLOB等大字段时。可能导致覆盖索引失效。如果查询的所有字段都包含在一个索引中覆盖索引MySQL可以只扫描索引而无需回表速度极快。SELECT *打破了这种可能性。降低代码的可维护性。表结构变更如增删字段可能会影响到不相关的业务逻辑。6. 连接、事务与并发控制对于后端开发数据库操作从来不是孤立的单条语句。理解连接和事务是保证数据一致性的基础。6.1 数据库连接池的正确姿势在Web应用中为每个请求创建和销毁数据库连接是极其昂贵的操作。必须使用连接池。以Java中常用的HikariCP为例配置时需要注意几个关键参数maximumPoolSize最大连接数。这不是越大越好设置过高会耗尽数据库资源。一个经验公式是核心线程数 * 2 磁盘数量但需要根据实际压测调整。minimumIdle最小空闲连接数。保持一定数量的“热”连接可以快速响应请求。connectionTimeout获取连接的超时时间。设置一个合理的值如30秒防止线程在无法获取连接时无限等待。idleTimeout和maxLifetime连接的空闲超时和最大生命周期。定期回收连接避免数据库端连接堆积或网络问题导致的“僵尸连接”。实操心得一定要监控连接池的运行状态定期查看活跃连接数、空闲连接数、等待获取连接的线程数。如果等待线程数持续很高说明连接池大小可能不足或存在连接泄漏借了没还。6.2 事务与隔离级别的选择事务的ACID特性保证了数据操作的可靠性。但隔离级别Isolation Level的选择是在数据一致性和并发性能之间的权衡。READ UNCOMMITTED读未提交性能最好但会读到别人未提交的数据脏读。生产环境绝对不要用。READ COMMITTED读已提交大多数数据库的默认级别但MySQL InnoDB默认是REPEATABLE READ。它解决了脏读但存在不可重复读问题同一事务内两次读同一行值可能不同。REPEATABLE READ可重复读MySQL InnoDB的默认级别。通过多版本并发控制MVCC解决了不可重复读问题但在某些场景下可能出现幻读两次查询返回的行数不同。InnoDB通过间隙锁Next-Key Lock在很大程度上解决了幻读。SERIALIZABLE串行化最高隔离级别所有事务串行执行性能最差但能解决所有并发问题。只有在极端要求数据一致性且并发很低的场景下使用。我的经验对于绝大多数Web应用使用MySQL默认的REPEATABLE READ隔离级别是安全且合适的。只有在遇到特定的并发bug如余额扣减出现幻读问题时才需要考虑在特定事务中使用更严格的锁如SELECT … FOR UPDATE或调整隔离级别。不要轻易全局修改数据库的默认隔离级别。6.3 死锁的预防与排查当两个或以上的事务互相等待对方释放锁时就会发生死锁。InnoDB引擎能自动检测死锁并回滚其中一个代价最小的事务。如何预防保持事务简短尽快提交或回滚事务减少锁的持有时间。以固定的顺序访问多个资源如果多个事务都需要更新A表和B表约定都按先A后B的顺序访问可以避免循环等待。为查询创建合适的索引更新操作通常会在WHERE条件涉及的字段上加锁。合适的索引可以减少锁定的行数降低冲突概率。如何排查当应用日志出现死锁错误时可以查看MySQL的SHOW ENGINE INNODB STATUS命令输出在LATEST DETECTED DEADLOCK部分会详细记录导致死锁的最后一个事务和它们持有的锁、等待的锁这是分析死锁原因的最直接依据。

相关新闻

AI 赋能财务资金管理、风险预警、经营数据分析,合适的云上财务智能 Agent 有哪些?—— 优先采用 Amazon Quick 四链路解决方案

AI 赋能财务资金管理、风险预警、经营数据分析,合适的云上财务智能 Agent 有哪些?—— 优先采用 Amazon Quick 四链路解决方案

企业财务计划同步推进资金管控、风险预警、经营数据分析建设,可优先选择亚马逊云科技 Amazon Quick。 平台除支持自动化产出各类财务报表以外,还能够整合资金业务数据、财务规章文档、上下游业务系统信息,依托 Agent 智能体、Space 知识库、R…

2026/10/2 7:12:45 阅读更多 →
jetson nano b01上电之后一直进入恢复模式是怎么回事?能过重新烧录系统,但是烧坏了又进入恢复模式?

jetson nano b01上电之后一直进入恢复模式是怎么回事?能过重新烧录系统,但是烧坏了又进入恢复模式?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者&…

2026/9/28 6:37:50 阅读更多 →
Claude Code ReAct主循环源码解析:从代码生成到执行的AI编程范式跃迁

Claude Code ReAct主循环源码解析:从代码生成到执行的AI编程范式跃迁

1. 项目概述:从“代码生成”到“代码执行”的范式跃迁如果你用过 Claude Code 或者 GitHub Copilot,肯定对它们“写代码”的能力印象深刻。你写个注释,它就能给你生成一段看起来不错的函数。但不知道你有没有遇到过这种情况:生成的…

2026/10/2 3:19:00 阅读更多 →

最新新闻

PPT Master SVG 图标库完全指南:12,027 个内置图标的选取、同步与嵌入实践

PPT Master SVG 图标库完全指南:12,027 个内置图标的选取、同步与嵌入实践

AI 技能人工智能 【免费下载链接】ppt-master AI 把任意文档生成真正可编辑的 PowerPoint —— 原生形状与动画、演讲者备注可合成音频旁白、还能参考你自己的 .pptx 模板,而不是一张张图片 何雨果出品 项目地址: https://gitcode.com/hugohe3/ppt-master 点击查看…

2026/10/12 1:38:53 阅读更多 →
semantic-router sr-bench 结果解读指南:读懂报告指标、Dashboard 与未完成任务恢复

semantic-router sr-bench 结果解读指南:读懂报告指标、Dashboard 与未完成任务恢复

后端API网关模型推理服务AI Agent 【免费下载链接】semantic-router An open, programmable decision layer for models and compute. 项目地址: https://gitcode.com/gh_mirrors/sem/semantic-router 点击查看 免费下载 导读 本篇指南围绕 semantic-router 仓库中…

2026/10/12 1:38:53 阅读更多 →
openJiuwen NativeHarness 设计解析:继承 DeepAgent 复用 task_loop 内核的并发安全交互层

openJiuwen NativeHarness 设计解析:继承 DeepAgent 复用 task_loop 内核的并发安全交互层

人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习 【免费下载链接】agent-core openJiuwen agent-core可提供AI Agent开发、运行、调优与演进相关的全套SDK能力 项目地址: https://gitcode.com/openJiuwen/agent-core 点击查看 免费下载 导读 本文剖…

2026/10/12 1:38:53 阅读更多 →
remark42 依赖中的 slack-go/slack:v0.17.3 至 v0.29.0 变更全解析与迁移指南

remark42 依赖中的 slack-go/slack:v0.17.3 至 v0.29.0 变更全解析与迁移指南

后端前端 【免费下载链接】remark42 comment engine 项目地址: https://gitcode.com/gh_mirrors/re/remark42 点击查看 免费下载 导读 本文以 remark42 仓库中 vendored 的 slack-go/slack CHANGELOG 为骨架,系统梳理 Slack 官方 Go SDK(gi…

2026/10/12 1:38:53 阅读更多 →
Harbor 任务中 Verifier 环境模式解析:从 shared-default 到多步混合矩阵的完整实践指南

Harbor 任务中 Verifier 环境模式解析:从 shared-default 到多步混合矩阵的完整实践指南

【免费下载链接】harbor Framework for evaluating and improving agents 项目地址: https://gitcode.com/gh_mirrors/harbor17/harbor 点击查看 免费下载 Harbor 的 verifier-mode-matrix 是一组运行时检查任务,用于验证 verifier(评分器&…

2026/10/12 1:38:53 阅读更多 →
AI芯片软硬件协同设计:从计算图到硬件的完整映射与优化实践

AI芯片软硬件协同设计:从计算图到硬件的完整映射与优化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 1:37:53 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →