mysql - MySQL 每个查询/子查询是否只使用一个索引?
问题描述
请假设以下查询:
select dic.*, d.syllable
from dictionary dic
join details d on d.word = dic.word
如您所知(我听说过),MySQL 每个查询只使用一个索引。现在我想知道,在上面的查询中,哪个索引会更好?
dictionary(word)
details(word)
换句话说,当有一个join
(涉及两个表)时,哪个索引会受到影响?我是否应该同时创建它们(在on
子句的列上)并且 MySQL 本身决定使用哪个更好?
解决方案
如您所知(我听说过),MySQL 每个查询只使用一个索引。
通常,大多数数据库在每个查询中每个表只使用一个索引。情况并非总是如此,但至少是一个不错的经验法则。对于您的特定示例,您可以依赖此。
现在我想知道,在上面的查询中,哪个索引会更好?
您编写的查询实际上是一个内部联接。这意味着两个表中的任何一个都可能出现在连接的左侧,并且结果集在逻辑上是等价的。因此,MySQL 可以自由地以它选择的任何顺序编写连接。选择的计划可能会将较大的桌子放在左侧,将较小的桌子放在右侧。如果您知道表的实际执行顺序,那么您只需索引正确的表。鉴于您可能不知道这一点,那么您建议的两个索引都是合理的:
CREATE INDEX dict_idx ON dictionary (word);
CREATE INDEX details_idx ON details (word);
我们甚至可以尝试通过覆盖出现在 select 子句中的列来改进上述索引。例如,索引 ondetails
可以扩展为:
CREATE INDEX details_idx ON details (word, syllable);
这将让 MySQL 专门使用上述索引来满足查询计划,而无需回溯到原始表。您选择dictionary.*
,因此使用单个索引覆盖它可能是不可能或不可取的,但至少这可以理解。
推荐阅读
- datetime - 搜索可供预订的物品
- python-3.x - 这怎么可能?最大子数组和
- node.js - WebSocket 握手期间出错:意外的响应代码:Minikube 上带有 Ingress 的 502
- bash - 使用文件中的“<”重定向数据时如何访问数据?
- docker - Kubernetes:使用 kubeadm 构建集群后,节点/Pods 未使用 kubectl 显示
- http - 为什么我不能在 Wireshark 中过滤 http?
- python - 为什么在将漂亮的数据切片转换为 png 图像时会得到完全黑色的标签?
- c++ - 如何移动变体的值
变成一个变种 ? - django - 尽管有 --schedulers 标志,但 django-celery-beat 的权限被拒绝错误
- opengl - 为什么统一变量在 GLSL 中不起作用?