国产高清在线免费观看-国产高清在线免费无码-国产高清在线男人的天堂-国产高清在线视频-国产高清在线视频精品视频-国产高清在线视频伊甸园

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

SQL隱式類型轉(zhuǎn)換 什么時(shí)候會(huì)導(dǎo)致索引失效

freeflydom
2025年4月15日 15:7 本文熱度 453

前言

在數(shù)據(jù)庫(kù)中,索引失效會(huì)導(dǎo)致查詢無(wú)法利用索引來(lái)加速,從而降低查詢性能。

今天就來(lái)探索為什么隱式類型轉(zhuǎn)換,會(huì)導(dǎo)致索引失效呢,為什么不能對(duì)參數(shù)進(jìn)行類型轉(zhuǎn)換再匹配呢,這樣不就能用上索引呢?

隱式類型轉(zhuǎn)換之謎??

為什隱式轉(zhuǎn)換會(huì)導(dǎo)致索引失效

先看一個(gè)例子: create_by 的字段類型為 varchar

看到這兒可能很多人都會(huì)大吃一驚!
MySQL 會(huì)嘗試將 VARCHAR 類型的 create_by 字段值轉(zhuǎn)換為數(shù)字類型,然后再與 116 進(jìn)行比較。在轉(zhuǎn)換過(guò)程中,MySQL 會(huì)從字符串的開(kāi)頭開(kāi)始解析數(shù)字,直到遇到非數(shù)字字符為止。如果字符串開(kāi)頭沒(méi)有有效的數(shù)字,那么轉(zhuǎn)換結(jié)果為 0

上面的SQL 和 下面這個(gè)SQL 執(zhí)行邏輯應(yīng)該是相似的
SELECT distinct create_by FROM t_message WHERE CONVERT(create_by, SIGNED) = 116;
換成這個(gè)SQL我想大家都明白了,為什么索引會(huì)失效了,隱式轉(zhuǎn)換的時(shí)候如果是對(duì)列轉(zhuǎn),那么索引就一定失效

隱式轉(zhuǎn)換索引一定失效么?轉(zhuǎn)換一定是轉(zhuǎn)列么?

當(dāng)然不是??,請(qǐng)看下面IDbigint,并且執(zhí)行執(zhí)行計(jì)劃是 使用了主鍵索引的

再來(lái)看一張人大金倉(cāng)的explain, 它這個(gè)就很清楚了,是把參數(shù)轉(zhuǎn)換成 數(shù)據(jù)庫(kù)列的類型,這樣就肯定走索引呢 : id = '123' ::bigint 如下

隱式轉(zhuǎn)換有什么規(guī)則呢?什么時(shí)候轉(zhuǎn)參數(shù),什么時(shí)候轉(zhuǎn)列

??其實(shí)Mysql轉(zhuǎn)換是有一套優(yōu)先級(jí)的: 數(shù)字類型 > 時(shí)間類型 > 字符串類型,低級(jí)向高級(jí)轉(zhuǎn)換。

??所以如果列類型的優(yōu)先級(jí)高于參數(shù)類型的優(yōu)先級(jí) 那么就會(huì)對(duì)參數(shù)進(jìn)行類型轉(zhuǎn)換,這時(shí)候類型轉(zhuǎn)換不會(huì)對(duì)性能有啥影響。反之會(huì)去對(duì)列數(shù)據(jù)進(jìn)行轉(zhuǎn)換,性能的影響就比較大

最近工作也遇到很多 數(shù)字 和 boolean 類型的轉(zhuǎn)換,在人大金倉(cāng)中是 將boolean類型轉(zhuǎn)為數(shù)字,mysql 沒(méi)做測(cè)試,應(yīng)該也是一樣。

為什么不能直接對(duì)參數(shù)轉(zhuǎn)換了,這樣就不會(huì)導(dǎo)致索引失效了?

MySQL在處理類型不匹配的比較時(shí),通常選擇轉(zhuǎn)換列值而非參數(shù)值,從而導(dǎo)致索引失效。這個(gè)設(shè)計(jì)決策背后主要是按照

?MySQL遵循SQL標(biāo)準(zhǔn)中"操作數(shù)類型提升"的規(guī)則,通常會(huì)將低優(yōu)先級(jí)類型轉(zhuǎn)換為高優(yōu)先級(jí)類型,數(shù)值類型優(yōu)先級(jí) > 時(shí)間類型 > 字符串類型

這種轉(zhuǎn)換方向是數(shù)據(jù)庫(kù)引擎的通用設(shè)計(jì)模式

為什么SQL標(biāo)準(zhǔn)"操作數(shù)類型提升" 要這樣設(shè)計(jì)呢

?下面看看DeepSeek 是怎么回答的?

1. 語(yǔ)義一致性(避免歧義)與可預(yù)測(cè)性

SQL 標(biāo)準(zhǔn)要求表達(dá)式的結(jié)果類型必須明確且可預(yù)測(cè)。當(dāng)操作數(shù)類型不同時(shí),通過(guò)固定的優(yōu)先級(jí)規(guī)則(如數(shù)值 > 時(shí)間 > 字符串)進(jìn)行隱式轉(zhuǎn)換,確保所有數(shù)據(jù)庫(kù)實(shí)現(xiàn)的行為一致。例如:

數(shù)值與字符串比較時(shí),字符串轉(zhuǎn)為數(shù)值,避免因字符編碼差異導(dǎo)致不確定結(jié)果。 假設(shè) 一個(gè)條件是 var_colum = 123, 如果轉(zhuǎn)換成 var_colum = '123' ,那么 ' 123 ' 這種有空格的就無(wú)法查詢了。這就是語(yǔ)義一致性問(wèn)題。

2. 計(jì)算效率優(yōu)化

高優(yōu)先級(jí)類型(如數(shù)值)通常具有更高效的比較和計(jì)算機(jī)制。例如:

數(shù)值比較直接使用CPU指令,而字符串比較需逐字符處理。優(yōu)先轉(zhuǎn)為數(shù)值可提升性能。

3. 索引結(jié)構(gòu)的限制

我也沒(méi)咋看懂??: 索引(如B-tree)按列的原生類型組織。若強(qiáng)制轉(zhuǎn)換參數(shù)而非列值,存儲(chǔ)引擎仍需按列類型重新轉(zhuǎn)換參數(shù),反而增加開(kāi)銷。例如:

WHERE varchar_col = 123 若轉(zhuǎn)為 varchar_col = '123',仍需將字符串'123'轉(zhuǎn)回?cái)?shù)值與索引比較,無(wú)法避免轉(zhuǎn)換。

總結(jié)

本篇文章,分析了查詢隱式轉(zhuǎn)換什么時(shí)候會(huì)索引失效,以及轉(zhuǎn)換規(guī)則優(yōu)先級(jí),以及為什么SQL標(biāo)準(zhǔn)要這么去定義,DeepSeek 給的答案是主要就是 避免歧義,提升性能。

推薦閱讀:dev.mysql.com/doc/refman/…?

知識(shí)擴(kuò)展

下面第一、二點(diǎn)就是我們今天探索的失效場(chǎng)景

  1. 類型不匹配 如果查詢條件中的數(shù)據(jù)類型與索引列的數(shù)據(jù)類型不一致,數(shù)據(jù)庫(kù)可能會(huì)進(jìn)行隱式類型轉(zhuǎn)換,破壞索引的有序性,造成索引失效。
-- 假設(shè) id 是varchar類型的索引列,參數(shù)傳一個(gè) 數(shù)字
SELECT * FROM users WHERE id = 123; 
  1. 索引列上使用函數(shù)或表達(dá)式 當(dāng)在索引列上使用函數(shù)、表達(dá)式時(shí),數(shù)據(jù)庫(kù)無(wú)法直接使用索引的有序結(jié)構(gòu)來(lái)快速定位數(shù)據(jù),通常會(huì)導(dǎo)致索引失效。
-- 例如在 MySQL 中,對(duì)索引列使用 UPPER 函數(shù)
SELECT * FROM users WHERE UPPER(name) = 'JOHN'; 
  1. 范圍查詢右側(cè)列 對(duì)于復(fù)合索引(多列索引),如果在復(fù)合索引的前導(dǎo)列使用范圍查詢,后續(xù)列的索引會(huì)失效。
-- 假設(shè)存在復(fù)合索引 (col1, col2)
SELECT * FROM table_name WHERE col1 > 10 AND col2 = 20; 
-- 此時(shí) col2 列的索引會(huì)失效
  1. 模糊查詢以通配符開(kāi)頭 在使用 LIKE 進(jìn)行模糊查詢時(shí),如果通配符 % 出現(xiàn)在字符串的開(kāi)頭,數(shù)據(jù)庫(kù)無(wú)法利用索引的有序性進(jìn)行快速匹配,會(huì)導(dǎo)致索引失效。
SELECT * FROM users WHERE name LIKE '%john'; 

5. OR 連接條件 當(dāng)查詢條件使用 OR 連接多個(gè)條件,且這些條件部分沒(méi)有索引或者不全使用同一個(gè)索引時(shí),可能會(huì)導(dǎo)致索引失效。

SELECT * FROM users WHERE id = 1 OR name = 'john'; 
-- 如果 id 有索引,name 沒(méi)有索引,可能導(dǎo)致索引失效

6. IS NULL 和 IS NOT NULL 在某些情況下,對(duì)索引列使用 IS NULL 或 IS NOT NULL 可能會(huì)導(dǎo)致索引失效,尤其是在數(shù)據(jù)分布不均勻時(shí)。

SELECT * FROM users WHERE email IS NULL; 
  1. 全表掃描更快 當(dāng)數(shù)據(jù)庫(kù)的查詢優(yōu)化器認(rèn)為全表掃描比使用索引掃描更快時(shí),會(huì)選擇全表掃描,此時(shí)索引就不會(huì)被使用。例如,當(dāng)查詢的數(shù)據(jù)量占總數(shù)據(jù)量的比例較大時(shí),優(yōu)化器可能會(huì)做出這樣的決策。

  2. 索引統(tǒng)計(jì)信息不準(zhǔn)確 如果索引的統(tǒng)計(jì)信息不準(zhǔn)確,查詢優(yōu)化器可能會(huì)做出錯(cuò)誤的決策,導(dǎo)致索引失效。例如,表數(shù)據(jù)發(fā)生了大量的插入、刪除、更新操作,但沒(méi)有及時(shí)更新索引統(tǒng)計(jì)信息。

  3. 強(qiáng)制索引失效 在 SQL 語(yǔ)句中使用 IGNORE INDEX 關(guān)鍵字可以強(qiáng)制數(shù)據(jù)庫(kù)不使用指定的索引。

轉(zhuǎn)自https://juejin.cn/post/7490856819003785252


該文章在 2025/4/15 15:07:35 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 亚洲欧美日韩国产一区二区 | 亚洲精品无码观看 | 無码一区中文字幕少妇熟女网站 | 国产欧美一区二区三区久久 | 99久久久无码国产精品AAA | 日日播天天播人人看 | 日韩av片无码一区二区不卡电影 | 国产成人精品尤物一区二区 | 欧美日本在线一区二区三区 | 91精品无码中文字幕在线不卡 | 国产精品亚洲二区在线观看 | 亚洲人成无码网站在线观看 | 日韩欧美视频在线观看一区免费 | 国产一级毛片潘金莲 | 91在线一区二区三区 | 国产成人无码手机免费 | 亚洲av中文无码乱人伦在线播放 | 精品无码一区二区视频在线 | 西西午夜无码大胆啪啪国模 | 综合亚洲日本日 | 亚洲av无码专区在线电影 | 欧美亚洲熟妇一区二区三区 | 极品少妇xxxx精品少妇偷拍 | 亚洲另类日韩图片区 | 亚洲永久精品中国无损音乐 | 无码刺激性av完整版 | 国产成人3p视频免费观看 | 亚洲真实片中文字幕 | 一本清日本在线视频精品 | 亚洲无线一线二线三线区别 | 亚洲一区在线免费 | 亚洲欧美日韩综合精品 | 亚洲国产成人久久一区 | 亚洲成a人片在线观看 | 少妇一级婬片免费放狠狠干狠狠躁 | 中文日产乱幕九区无线码 | 久久精品国产www456c0m | 国产人妻无码一区二区三区免费 | 色综合久久久久综合 | 欧美日韩精品视频一区二区三区 | 一本久道久久综合婷婷五月 |