最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL字符集不一致導(dǎo)致索引失效的解決辦法

 更新時間:2024年04月16日 10:32:05   作者:不剪發(fā)的Tony老師  
本文分析了一個由于字符集不一致,導(dǎo)致增加了索引但是無法使用的案例,通過索引進行查找時需要進行數(shù)據(jù)的比較,字符集不一致時需要使用 convert 函數(shù)進行轉(zhuǎn)換,從而導(dǎo)致索引失效,文中有詳細的解決辦法,需要的朋友可以參考下

問題描述

有個朋友給我發(fā)來一個問題,說是他們的系統(tǒng)有幾十萬用戶,某個查詢需要 5 秒以上的時間才能返回,同時服務(wù)器 CPU 資源占用率將近 100%。這個對于用戶的線上操作影響非常大,那么我們就來看看如何分析和解決這個慢查詢問題。

為了便于說明問題,我們對表結(jié)構(gòu)進行了簡化:

create table customer(
  cid int auto_increment primary key,
  cname varchar(50) not null,
  register_time datetime not null,
  recommender varchar(50) character set utf8
) engine=innodb default charset=utf8mb4;

create unique index uk_customer_cname on customer(cname);

insert into customer(cname, register_time, recommender) values('張三', now(), '');
insert into customer(cname, register_time, recommender) values('李四', now(), '張三'),('王五', now(), '李四');

customer 是用戶表,其中 cid 是主鍵;cname 上有一個唯一索引;recommender 是用戶的推薦人。

實際查詢涉及了很多表,經(jīng)過簡化之后存在性能問題的語句如下:

select c.*
from customer c
join customer r on (c.recommender = r.cname )
where r.cid = 1
and c.register_time between now() - interval 1 day and now();

大意是查找通過某人推薦,在指定時間段內(nèi)注冊的用戶。

問題分析

了解問題之后,首先我讓他給我發(fā)來了 explain 執(zhí)行計劃:

explain
select c.*
from customer c
join customer r on (c.recommender = r.cname )
where r.cname = '張三'
and c.register_time between now() - interval 1 day and now();

id|select_type|table|partitions|type |possible_keys    |key              |key_len|ref  |rows|filtered|Extra      |
--|-----------|-----|----------|-----|-----------------|-----------------|-------|-----|----|--------|-----------|
 1|SIMPLE     |r    |          |const|uk_customer_cname|uk_customer_cname|202    |const|   1|   100.0|Using index|
 1|SIMPLE     |c    |          |ALL  |                 |                 |       |     |   3|   33.33|Using where|

從結(jié)果可以看出,有一個全表掃描(type = ALL)的操作,顯然這是因為 recommender 字段上缺少索引。

所以,我們首先為 recommender 字段創(chuàng)建了一個索引:

create index idx_customer_cname on customer(recommender);

之后再次查看了執(zhí)行計劃,結(jié)果沒有任何變化,創(chuàng)建的索引沒有生效。然后我們使用了 show warnings 命令看看有沒有更多的信息:

show warnings\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select `hrdb`.`c`.`cid` AS `cid`,`hrdb`.`c`.`cname` AS `cname`,`hrdb`.`c`.`register_time` AS `register_time`,`hrdb`.`c`.`recommender` AS `recommender` from `hrdb`.`customer` `c` join `hrdb`.`customer` `r` where ((`hrdb`.`c`.`register_time` between <cache>((now() - interval 1 day)) and <cache>(now())) and (convert(`hrdb`.`c`.`recommender` using utf8mb4) = '張三'))
1 row in set (0.00 sec)

這里有一個問題,就是存在字符集轉(zhuǎn)換:

convert(`hrdb`.`c`.`recommender` using utf8mb4) = '張三')

recommender 需要轉(zhuǎn)換為 utf8mb4 字符集,查看表結(jié)構(gòu)之后發(fā)現(xiàn)它的字符集是 utf8,和表中的其他字段字符集不一樣。原來他們是從之前的版本遷移過來的表結(jié)構(gòu),不知怎么會導(dǎo)致遺留一個字段的字符集忘記了調(diào)整。

MySQL 支持數(shù)據(jù)庫、表以及字段級別的字符集(Character Set)和排序規(guī)則(Collation)。不同字符集支持的字符種類和數(shù)量不同,例如 ASCII 字符集只能存儲字母、數(shù)字和常見的符號,GB2312 和 GB18030 可以支持中文,Unicode 字符集能夠支持多國語言;排序規(guī)則定義了字符的排序順序,例如是否區(qū)分大小寫、是否區(qū)分重音、中文按照拼音還是偏旁進行排序等。

接下來就是修改字段的字符集了:

alter table customer modify column recommender varchar(50) character set utf8mb4;

然后,再次查看執(zhí)行計劃的結(jié)果如下:

id|select_type|table|partitions|type |possible_keys     |key               |key_len|ref  |rows|filtered|Extra      |
--|-----------|-----|----------|-----|------------------|------------------|-------|-----|----|--------|-----------|
 1|SIMPLE     |r    |          |const|uk_customer_cname |uk_customer_cname |202    |const|   1|   100.0|Using index|
 1|SIMPLE     |c    |          |ref  |idx_customer_cname|idx_customer_cname|203    |const|   1|   33.33|Using where|

在實際環(huán)境中優(yōu)化之后的查詢需要 0.1 秒左右,已經(jīng)完全可以滿足業(yè)務(wù)的需求了。

總結(jié)

本文分析了一個由于字符集不一致,導(dǎo)致增加了索引但是無法使用的案例。通過索引進行查找時需要進行數(shù)據(jù)的比較,字符集不一致時需要使用 convert 函數(shù)進行轉(zhuǎn)換,從而導(dǎo)致索引失效。通常在遷移遺留系統(tǒng)時需要特別小心,對于 Unicode 推薦使用最新的 utf8mb4 字符集。

以上就是MySQL字符集不一致導(dǎo)致索引失效的解決辦法的詳細內(nèi)容,更多關(guān)于MySQL字符集不一致的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL?到Oracle?實時數(shù)據(jù)同步

    MySQL?到Oracle?實時數(shù)據(jù)同步

    這篇文章主要介紹了MySQL?到Oracle?實時數(shù)據(jù)同步,本次?MySQL?數(shù)據(jù)實時同步到?Oracle大概只花了幾分鐘就完成。使用的工具是Tapdata?Cloud?,這個工具是永久免費的,需要的朋友可以參考一下
    2022-01-01
  • MySQL9.0.1安裝教程的實現(xiàn)示例

    MySQL9.0.1安裝教程的實現(xiàn)示例

    本文主要介紹了MySQL軟件的下載、解壓、環(huán)境變量配置、初始化及啟動、登錄與密碼設(shè)置等步驟,詳細說明了每一步的操作方法,感興趣的可以了解一下
    2024-10-10
  • MySQL從零開始了解數(shù)據(jù)庫開發(fā)之表的操作解析

    MySQL從零開始了解數(shù)據(jù)庫開發(fā)之表的操作解析

    這篇文章介紹了MySQL中數(shù)據(jù)表的基本操作,包括創(chuàng)建、修改和刪除表的相關(guān)語法和注意事項,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-09-09
  • mysql regexp匹配多個字符串實現(xiàn)

    mysql regexp匹配多個字符串實現(xiàn)

    本文主要介紹了mysql regexp匹配多個字符串實現(xiàn),可以利用REGEXP正則表達式匹配多個字符串,從而實現(xiàn)高效查詢,具有一定的參考價值,感興趣的可以了解一下
    2024-09-09
  • 結(jié)合PHP腳本添加和查詢MySQL數(shù)據(jù)的基本教程

    結(jié)合PHP腳本添加和查詢MySQL數(shù)據(jù)的基本教程

    這篇文章主要介紹了結(jié)合PHP腳本添加和查詢MySQL數(shù)據(jù)的基本教程,即在PHP程序中使用基本的SELECT FROM和INSERT INTO語句,需要的朋友可以參考下
    2015-12-12
  • mysql datetime查詢異常問題解決

    mysql datetime查詢異常問題解決

    這篇文章主要介紹了mysql datetime查詢異常問題解決的相關(guān)資料,這里對異常進行了詳細的介紹和該如何解決,需要的朋友可以參考下
    2016-11-11
  • mysql 5.7.16 zip包安裝配置方法圖文教程

    mysql 5.7.16 zip包安裝配置方法圖文教程

    這篇文章主要為大家分享了mysql 5.7.16 zip包安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • mysql派生表(Derived Table)簡單用法實例解析

    mysql派生表(Derived Table)簡單用法實例解析

    這篇文章主要介紹了mysql派生表(Derived Table)簡單用法,結(jié)合實例形式分析了mysql派生表的原理、簡單使用方法及操作注意事項,需要的朋友可以參考下
    2019-12-12
  • Navicat如何遠程連接云服務(wù)器數(shù)據(jù)庫

    Navicat如何遠程連接云服務(wù)器數(shù)據(jù)庫

    這篇文章主要介紹了Navicat如何遠程連接云服務(wù)器數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • mysql 操作數(shù)據(jù)庫基礎(chǔ)詳解

    mysql 操作數(shù)據(jù)庫基礎(chǔ)詳解

    這篇文章主要介紹了mysql 操作數(shù)據(jù)庫基礎(chǔ)詳解,MySQL是一種關(guān)系型數(shù)據(jù)庫管理系統(tǒng),關(guān)系數(shù)據(jù)庫將數(shù)據(jù)保存在不同的表中,而不是將所有數(shù)據(jù)放在一個大倉庫內(nèi),這樣就增加了速度并提高了靈活性
    2022-08-08

最新評論

稻城县| 兴国县| 隆安县| 吴川市| 定州市| 山东| 搜索| 洪洞县| 增城市| 锡林浩特市| 屏山县| 怀来县| 中方县| 松桃| 明溪县| 淅川县| 平度市| 黑龙江省| 吴江市| 静乐县| 濉溪县| 祁阳县| 永善县| 礼泉县| 和静县| 杭锦后旗| 封丘县| 随州市| 屏山县| 平山县| 庄河市| 双辽市| 临西县| 石狮市| 沁水县| 清水县| 乌兰察布市| 开化县| 易门县| 孝昌县| 广灵县|