gpt4 book ai didi

mysql - 为什么MySQL不使用索引?

转载 作者:行者123 更新时间:2023-11-28 23:54:25 25 4
gpt4 key购买 nike

我有两个表:(省略了与这个问题无关的列):

CREATE TABLE 'oc_room' (
'id' int(11) NOT NULL AUTO_INCREMENT,
'house_id' int(11) NOT NULL,
'style_id' int(11) DEFAULT NULL,
'weight' int(11) DEFAULT '0',
'state' tinyint(4) DEFAULT '0',
-- (more columns, omitted for clarity)
PRIMARY KEY ('id'),
KEY 'house_id' ('house_id'),
KEY 'style_id' ('style_id'),
KEY 'butler_id' ('butler_id'),
KEY 'oc_room_house_state_hidden_ik_1' ('house_id','state','hidden'),
CONSTRAINT 'oc_room_ibfk_1' FOREIGN KEY ('house_id') REFERENCES 'oc_house' ('id'),
CONSTRAINT 'oc_room_ibfk_2' FOREIGN KEY ('style_id') REFERENCES 'oc_room_style' ('id'),
CONSTRAINT 'oc_room_ibfk_3' FOREIGN KEY ('butler_id') REFERENCES 'oc_butler' ('id')
) ENGINE=InnoDB AUTO_INCREMENT=267 DEFAULT CHARSET=utf8;

CREATE TABLE 'oc_circle_of_community' (
'id' int(11) NOT NULL AUTO_INCREMENT,
'circle_id' int(11) NOT NULL,
'community_id' int(11) NOT NULL,
PRIMARY KEY ('id'),
KEY 'circle_id' ('circle_id'),
KEY 'community_id' ('community_id'),
CONSTRAINT 'oc_circle_of_community_ibfk_1' FOREIGN KEY ('circle_id') REFERENCES 'oc_circle' ('id'),
CONSTRAINT 'oc_circle_of_community_ibfk_2' FOREIGN KEY ('community_id') REFERENCES 'oc_community' ('id')
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;

当我解释一个选择语句时,我有两个问题

问题一:

让我们从两张图片开始:

图片-1: enter image description here

图片-2: enter image description here请特别注意 explain 输出的底线。

然后将PIC-1中的表格与PIC-2中的表格进行比较。你会发现:

  1. PIC-1 中 oc_room 的选择使用组合键 oc_room_house_state_hidden_​​ik_1
  2. 那么在PIC-2中,没有用到key。
  3. 两个语句的唯一区别是oc_room.id in (5,7,9,20,40,60 )被替换
oc_room.id in 
( select id
from oc_house
where community_id in
( select community_id
from oc_circle_of_community
where circle_id in
( select id
from oc_circle
where oc_circle.district_id in
( select id
from oc_district
where oc_district.id = 3 ))))

为什么不同?

oc_room 总共有大约 300 行。

问题2:

查看表的 PIC-2,第 2 行,它解释了表 oc_circle_of_community 的选择。有两个可能的键:circle_idcommunity_id。为什么这两个键不能用?
(表 oc_circle_of_community 中共有 14 行。这可能会有所帮助。)

最佳答案

来自 bottom 处的手册.

Indexes are less important for queries on small tables, or big tables where report queries process most or all of the rows. When a query needs to access most of the rows, reading sequentially is faster than working through an index. Sequential reads minimize disk seeks, even if not all the rows are needed for the query.

图片-1

a) 300 行对于它来说太小了,无法在单个索引上进行磨练并随后进行扫描,因此它根本不会关心索引,或者

b) 你试图使用一个足够的复合索引,或者

c) 你用 covering index 去拿金牌并避免读取数据页

但是注意,它在 8 行中解决了它,而不是 300。它与复合 (house_id,state,hidden ),最后一个不是你显示的。总共 7 个字节宽。

因为您只有 300 行,analyze table 应该需要一瞬间。它刷新可能变得陈旧的 key 分布的统计数据,从而强制不使用 key 。 key 可能是使用目标,但最终在执行期间被放弃。因此,这是关于其用途的一般性陈述,例如对于大型表格,而不是您的问题。

图片-2

REF NULL 的 14 行与本答案的开头有关。

关于mysql - 为什么MySQL不使用索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32048691/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com