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

Mysql中條件字段有索引,但使用不了索引的幾種場景詳解

 更新時間:2025年04月27日 08:45:45   作者:_小魚塘  
這篇文章主要介紹了Mysql中條件字段有索引,但使用不了索引的幾種場景,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Mysql條件字段有索引,但使用不了索引的場景

對于 MySQL 而言,如果需要查找某一行的值,可以先通過索引找到對應(yīng)的值,然后根據(jù)索引匹配的記錄找到需要查詢的數(shù)據(jù)行。然而,有時會發(fā)現(xiàn),即使查詢條件有索引,也會查詢很慢;

下面會講解幾種有索引但是查詢不走索引導(dǎo)致查詢慢的場景。

一、前期準(zhǔn)備

drop table if exists t1;        /* 如果表t1存在則刪除表t1 */

CREATE TABLE `t1` (             /* 創(chuàng)建表t1 */
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` varchar(20) DEFAULT NULL,
  `b` int(20) DEFAULT NULL,
  `c` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  PRIMARY KEY (`id`),
  KEY `idx_a` (`a`) USING BTREE,
  KEY `idx_b` (`b`) USING BTREE,
  KEY `idx_c` (`c`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

drop procedure if exists insert_t1; /* 如果存在存儲過程insert_t1,則刪除 */
delimiter ;;
create procedure insert_t1()        /* 創(chuàng)建存儲過程insert_t1 */
begin
  declare i int;                    /* 聲明變量i */
  set i=1;                          /* 設(shè)置i的初始值為1 */
  while(i<=10000)do                 /* 對滿足i<=10000的值進行while循環(huán) */
    insert into t1(a,b) values(i,i);  /* 寫入表t1中a、b兩個字段,值都為i當(dāng)前的值 */
    set i=i+1;                        /* 將i加1 */
  end while;
end;;
delimiter ;
call insert_t1();                    /* 運行存儲過程insert_t1 */

update t1 set c = '2019-05-22 00:00:00';  /* 更新表t1的c字段,值都為'2019-05-22 00:00:00' */
update t1 set c = '2019-05-21 00:00:00' where id=10000;	 /* 將id為10000的行的c字段改為與其它行都不一樣的數(shù)據(jù),以便后面實驗使用 */

二、函數(shù)操作

在使用 MySQL 查詢數(shù)據(jù)時,可能很多時候會借助一些函數(shù)實現(xiàn)查詢。有時可能我們關(guān)注的重心在是否能查出結(jié)果,往往忽略了查詢的效率;

對于上面創(chuàng)建的測試表,比如要查詢測試表 t1 單獨某一天的所有數(shù)據(jù),SQL如下:

結(jié)果如下所示:

type 為 ALL,key 字段結(jié)果為 NULL,因此知道該 SQL 是沒走索引的全表掃描;

結(jié)論一:對條件字段做函數(shù)操作走不了索引;

如果需要優(yōu)化的話,改成 c 字段實際值相匹配的形式。因為 SQL 的目的是查詢 2019-05-21 當(dāng)天所有的記錄,因此可以改成范圍查詢,結(jié)果如下所示:

類似求某一天或者某一個月數(shù)據(jù)的需求,建議寫成類似上例的范圍查詢,可讓查詢能走索引。避免對條件索引字段做函數(shù)處理;

三、隱式轉(zhuǎn)換

隱式轉(zhuǎn)換:當(dāng)操作符與不同類型的操作對象一起使用時,就會發(fā)生類型轉(zhuǎn)換以使操作兼容。

某些轉(zhuǎn)換是隱式的;更多信息可以參考官網(wǎng):MySQL :: MySQL 5.7 Reference Manual :: 12.3 Type Conversion in Expression Evaluation

隱式轉(zhuǎn)換估計是很多 MySQL 使用者踩過的坑,比如聯(lián)系方式字段。由于有時電話號碼帶加、減等特殊字符,有時需要以 0 開頭,因此一般設(shè)計表時會使用 varchar 類型存儲,并且會經(jīng)常做為條件來查詢數(shù)據(jù),所以會添加索引;

比如我們要查詢 a 字段等于 1000 的值, 仔細對比下面兩個查詢:

a 字段類型是 varchar(20),而語句中 a 字段條件值沒加單引號,導(dǎo)致 MySQL 內(nèi)部會先把a轉(zhuǎn)換成int型,再去做判斷,再次印證了結(jié)論一:對索引字段做函數(shù)操作時,優(yōu)化器會放棄使用索引;

所以建議在寫SQL時,先看字段類型,然后根據(jù)字段類型寫SQL;

四、模糊查詢

很多時候我們想根據(jù)某個字段的某幾個關(guān)鍵字查詢數(shù)據(jù),比如會有如下 SQL:結(jié)果如下圖所示:

模糊查詢優(yōu)化建議:修改業(yè)務(wù),讓模糊查詢必須包含條件字段前面的值;如果條件只知道中間的值,需要模糊查詢?nèi)ゲ?,那就建議使用ElasticSearch或其它搜索服務(wù)器。

優(yōu)化后結(jié)果如下:

五、范圍查詢

拿測試表舉例,比如要取出b字段1到3000范圍數(shù)據(jù),SQL 如下 :

結(jié)論二:單次查詢的數(shù)據(jù)量過大,優(yōu)化器將不走索引,優(yōu)化范圍查詢:降低單次查詢范圍,分多次查詢:

實際這種范圍查詢而導(dǎo)致使用不了索引的場景經(jīng)常出現(xiàn),比如按照時間段抽取全量數(shù)據(jù),每條SQL抽取一個月的;或者某張業(yè)務(wù)表歷史數(shù)據(jù)的刪除。遇到此類操作時,應(yīng)該在執(zhí)行之前對SQL做explain分析,確定能走索引,再進行操作;

六、計算操作

有時我們與有對條件字段做計算操作的需求,在使用 SQL 查詢時,就應(yīng)該小心了;

優(yōu)化后結(jié)果:

結(jié)論三:一般需要對條件字段做計算時,建議通過程序代碼實現(xiàn),而不是通過MySQL實現(xiàn)。如果在MySQL中計算的情況避免不了,那必須把計算放在等號后面

總結(jié)

應(yīng)該避免隱式轉(zhuǎn)換、like查詢不能以%開頭,范圍查詢時,包含的數(shù)據(jù)比例不能太大,不建議對條件字段做運算及函數(shù)操作;

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MySQL LIKE 子句的具體使用

    MySQL LIKE 子句的具體使用

    LIKE子句用于在SQL查詢中進行模式匹配,支持%和_通配符,它可以用于查找包含特定子字符串或匹配特定格式的字符串,下面就來詳細的介紹一下MySQL LIKE 子句的實現(xiàn)
    2026-01-01
  • 獲取MySQL的表中每個userid最后一條記錄的方法

    獲取MySQL的表中每個userid最后一條記錄的方法

    這篇文章主要介紹了獲取MySQL的表中每個userid最后一條記錄的方法,并且針對userid不唯一的情況,需要的朋友可以參考下
    2015-05-05
  • MySQL使用Sequence創(chuàng)建唯一主鍵的實現(xiàn)示例

    MySQL使用Sequence創(chuàng)建唯一主鍵的實現(xiàn)示例

    Sequence提供了更多的靈活性,本文主要介紹了MySQL使用Sequence創(chuàng)建唯一主鍵的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • MySQL8.0.20安裝教程及其安裝問題詳細教程

    MySQL8.0.20安裝教程及其安裝問題詳細教程

    這篇文章主要介紹了MySQL8.0.20安裝教程及其安裝問題處理,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • mybatis分頁插件pageHelper詳解及簡單實例

    mybatis分頁插件pageHelper詳解及簡單實例

    這篇文章主要介紹了mybatis分頁插件pageHelper詳解及簡單實例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • VPS下修改MySQL root用戶密碼的方法

    VPS下修改MySQL root用戶密碼的方法

    VPS下修改MySQL root用戶密碼的方法,需要的朋友可以參考下。
    2010-12-12
  • mysql 索引分類以及用途分析

    mysql 索引分類以及用途分析

    MySQL索引分為普通索引、唯一性索引、全文索引、單列索引、多列索引等等。這里將為大家介紹著幾種索引各自的用途。
    2011-08-08
  • MySQL曝中間人攻擊Riddle漏洞可致用戶名密碼泄露的處理方法

    MySQL曝中間人攻擊Riddle漏洞可致用戶名密碼泄露的處理方法

    Riddle漏洞存在于DBMS Oracle MySQL中,攻擊者可以利用漏洞和中間人身份竊取用戶名和密碼。下面小編給大家?guī)砹薓ySQL曝中間人攻擊Riddle漏洞可致用戶名密碼泄露的處理方法,需要的朋友參考下吧
    2018-01-01
  • mysql 8.0.11 MSI版安裝配置圖文教程

    mysql 8.0.11 MSI版安裝配置圖文教程

    這篇文章主要為大家詳細介紹了mysql 8.0.11 MSI版安裝配置圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • mysql如何通過my.ini更改默認字符集

    mysql如何通過my.ini更改默認字符集

    這篇文章主要介紹了mysql如何通過my.ini更改默認字符集問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12

最新評論

长白| 三原县| 谷城县| 莲花县| 德清县| 游戏| 祁东县| 孟州市| 乡城县| 阿合奇县| 渝北区| 阿拉善右旗| 钦州市| 筠连县| 体育| 综艺| 左权县| 若羌县| 疏附县| 昌吉市| 那坡县| 瑞金市| 虎林市| 仙游县| 安图县| 吐鲁番市| 房山区| 岳阳县| 仙游县| 城固县| 吐鲁番市| 开封县| 麦盖提县| 遂川县| 固镇县| 阳泉市| 即墨市| 鄂尔多斯市| 遂川县| 黄石市| 拉孜县|