一烙常、問題描述
頁面一個列表查詢接口讀取經(jīng)常超時寒瓦。對應的數(shù)據(jù)來源于2張表的join。
SELECT
*
FROM
user_comment c
JOIN
user u ON u.id = c.user_id
where c.id = 1
對應表結(jié)構(gòu)
CREATE TABLE `user` (
`id` char(32) NOT NULL,
`name` varchar(64) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8_general_ci;
CREATE TABLE `user_comment` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` char(32) NOT NULL,
`comment` text,
PRIMARY KEY (`id`),
KEY `idx_userId` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
user_comment
里user_id有索引滴须,user
里id是主鍵台猴。但是使用explain
卻發(fā)現(xiàn)沒有走索引:
圖1.explain
二朽合、問題原因
user_comment
表為了能保存emoj表情而使用了utf8mb4編碼格式,但是user
表默認為utf8饱狂。所以join條件中的字段的因在兩張表中編碼不同而不會走索引曹步。
三、問題修復
修改user_comment
表默認編碼為utf8休讳,并單獨修改comment
字段編碼格式為utf8mb4讲婚。
ALTER TABLE `user_comment`
CHARACTER SET = utf8 , COLLATE = utf8_general_ci ,
CHANGE COLUMN `comment` `comment` TEXT CHARACTER SET 'utf8mb4' NULL DEFAULT NULL ;
四、改進方案
數(shù)據(jù)庫使用utf8mb4需謹慎俊柔,只針對需要的字段進行修改筹麸。
五、擴展
explain之type
type表示訪問類型:
- const:主鍵或唯一索引等值掃描雏婶。
- eq_ref:跨表join時物赶,主鍵索引(primary key)或者非空唯一索引(unique not null)等值掃描。
- ref:非主鍵并且非唯一索引等值掃描留晚。
- range:范圍掃描酵紫。
- index:索引樹掃描,如count(*)全表错维。
- ALL:全表掃描(full table scan)奖地。
掃描效率由快到慢:
const > eq_ref > ref > range > index > ALL