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

MySQL強(qiáng)制索引中USE/FORCE INDEX用法與避坑

 更新時(shí)間:2026年03月10日 09:26:13   作者:Hoffer_  
本文主要介紹了MySQL強(qiáng)制索引中USE/FORCE INDEX用法與避坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

MySQL 的查詢優(yōu)化器會(huì)根據(jù)統(tǒng)計(jì)信息(如基數(shù)、數(shù)據(jù)分布)自動(dòng)選擇它認(rèn)為 “最優(yōu)” 的索引。但有時(shí)它的判斷可能不準(zhǔn),這時(shí)就需要我們手動(dòng)干預(yù),這時(shí)候就用到這兩個(gè)語(yǔ)法:

  • USE INDEX:給優(yōu)化器一個(gè) “建議列表”,告訴它 “你可以從這些索引里選一個(gè)”,但它最終可能還是不采納。
  • FORCE INDEX:給優(yōu)化器一個(gè) “強(qiáng)制命令”,告訴它 “你必須用這個(gè)索引”,沒(méi)有商量余地。

一、USE INDEX 語(yǔ)法

SELECT *
FROM customer
USE INDEX (idx_last_name_first_name)  -- 放在 FROM 子句之后
WHERE last_name = 'BARBEE';
  • USE INDEX 后面跟著一個(gè)索引名列表,優(yōu)化器只能從這個(gè)列表里選擇。
  • 如果想讓優(yōu)化器忽略某些索引,可以用 IGNORE INDEX。

1、關(guān)鍵區(qū)別:USE(建議) vs FORCE(強(qiáng)制)

特性USE INDEXFORCE INDEX
性質(zhì)建議(Hint)強(qiáng)制(Force)
優(yōu)化器態(tài)度可以采納,也可以忽略必須執(zhí)行,沒(méi)有選擇
適用場(chǎng)景優(yōu)化器選錯(cuò)索引,但你有更好的候選優(yōu)化器完全不使用索引,導(dǎo)致性能極差
風(fēng)險(xiǎn)低,只是提供選項(xiàng)高,強(qiáng)制使用可能導(dǎo)致更差的性能

2、實(shí)戰(zhàn)場(chǎng)景:什么時(shí)候用?

>>DESC customer;
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
| Field       | Type              | Null | Key | Default           | Extra                                         |
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
| customer_id | smallint unsigned | NO   | PRI | NULL              | auto_increment                                |
| store_id    | tinyint unsigned  | NO   | MUL | NULL              |                                               |
| first_name  | varchar(45)       | NO   |     | NULL              |                                               |
| last_name   | varchar(45)       | NO   | MUL | NULL              |                                               |
| email       | varchar(50)       | YES  |     | NULL              |                                               |
| address_id  | smallint unsigned | NO   | MUL | NULL              |                                               |
| active      | tinyint(1)        | NO   |     | 1                 |                                               |
| create_date | datetime          | NO   |     | NULL              |                                               |
| last_update | timestamp         | YES  |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
+-------------+-------------------+------+-----+-------------------+-----------------------------------------------+
9 rows in set (0.00 sec)

場(chǎng)景一:優(yōu)化器選錯(cuò)了索引

在創(chuàng)建idx_last_name 和 idx_last_name_first_name 兩個(gè)索引后,

CREATE INDEX idx_last_name
ON customer (last_name);
CREATE INDEX idx_last_name_first_name
ON customer (last_name, first_name);

用 EXPLAIN 語(yǔ)句查看以下查找姓氏為 BARBEE 的語(yǔ)句的執(zhí)行計(jì)劃,

EXPLAIN
SELECT *
FROM customer
WHERE last_name = 'BARBEE';

但發(fā)現(xiàn)使用 idx_last_name_first_name 更好.

EXPLAIN
SELECT * 
FROM customer
USE INDEX(id_last_name_first_name)
WHERE last_name = 'BARBEE';

就像例子里的情況:

  • 表 customer 有兩個(gè)索引:idx_last_name 和 idx_last_name_first_name。
  • 查詢 WHERE last_name = 'BARBEE' 時(shí),優(yōu)化器選了 idx_last_name。
  • 但你通過(guò)分析,認(rèn)為 idx_last_name_first_name 更適合后續(xù)的排序或覆蓋索引需求。
  • 這時(shí)用 USE INDEX (idx_last_name_first_name) 來(lái)引導(dǎo)它。

場(chǎng)景二:優(yōu)化器完全不用索引

當(dāng)你的查詢條件明明有索引,但優(yōu)化器因?yàn)榻y(tǒng)計(jì)信息過(guò)時(shí)等原因,選擇了全表掃描,導(dǎo)致查詢極慢。這時(shí)就需要用 FORCE INDEX 來(lái)強(qiáng)制它使用索引。

二、FORCE INDEX 語(yǔ)法

MySQL 查詢優(yōu)化器會(huì)根據(jù)統(tǒng)計(jì)信息(如數(shù)據(jù)分布、基數(shù))自動(dòng)選擇執(zhí)行計(jì)劃。但在某些情況下,它的判斷可能 “短視”,導(dǎo)致性能不佳。所以FORCE INDEX 就是用來(lái)強(qiáng)制它必須使用你指定的索引。

這里有一個(gè)film表,顯示其索引(配合下文瀏覽即可):

+-------+------------+-----------------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name                    | Seq_in_index | Column_name          | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+-----------------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| film  |          0 | PRIMARY                     |            1 | film_id              | A         |        1000 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| film  |          1 | idx_title                   |            1 | title                | A         |        1000 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| film  |          1 | idx_fk_language_id          |            1 | language_id          | A         |           1 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| film  |          1 | idx_fk_original_language_id |            1 | original_language_id | A         |           1 |     NULL |   NULL | YES  | BTREE      |         |               | YES     | NULL       |
+-------+------------+-----------------------------+--------------+----------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
4 rows in set (0.00 sec)

1、為什么優(yōu)化器“不聽(tīng)話”?

案例:在film表查找語(yǔ)言為英語(yǔ)的影片(id = 1):

SELECT *
FROM film
WHERE language_id = 1;

但在查看這個(gè)語(yǔ)句的執(zhí)行計(jì)劃的時(shí)候(用EXPLAIN語(yǔ)句)——

發(fā)現(xiàn)MySQL 查詢優(yōu)化器并沒(méi)有使用 idx_fk_language_id 索引。這是因?yàn)?film 表中的所有影片都是英文影片,因此 MySQL 查詢優(yōu)化器指定全表掃描。

所以在這個(gè)例子中的 film 表:

  • 表中有 idx_fk_language_id 索引,查詢條件也是 WHERE language_id = 1。
  • 但優(yōu)化器選擇了全表掃描(type: ALL),因?yàn)樗l(fā)現(xiàn)表中幾乎所有行的 language_id 都是 1(英文電影)。
  • 對(duì)它來(lái)說(shuō),全表掃描比走索引更快,因?yàn)樗饕乇淼拈_(kāi)銷超過(guò)了收益?。?!

優(yōu)化器的邏輯是:當(dāng)查詢需要返回大部分?jǐn)?shù)據(jù)時(shí),全表掃描可能更高效,比走索引 + 回表的方式更快。

那么如果我們要用FORCE INDEX強(qiáng)制索引:

EXPLAIN
SELECT * 
FROM film
FORCE INDEX (id_fk_language_id) -- FORCE INDEX 后面跟著一個(gè)索引名列表,優(yōu)化器必須從這個(gè)列表中選擇一個(gè); 當(dāng)然如果列表中的索引不可用,查詢會(huì)報(bào)錯(cuò)。
WHERE language_id = 1;

這個(gè)例子只是為了舉例而用FORCE INDEX...

2、避坑

  1. 不要濫用:優(yōu)先讓優(yōu)化器自己做決定,只有在確認(rèn)它判斷錯(cuò)誤時(shí)才手動(dòng)干預(yù)。
  2. 驗(yàn)證性能:強(qiáng)制使用索引后,一定要用實(shí)際執(zhí)行時(shí)間來(lái)驗(yàn)證性能是否真的提升了。但在這個(gè)例子中,強(qiáng)制使用索引反而可能更慢,因?yàn)樾枰乇碜x取所有行。
  3. 覆蓋索引:如果查詢的所有列都在索引中(覆蓋索引),強(qiáng)制使用索引通常是有益的;如果需要回表,就要謹(jǐn)慎。
  4. 使用前務(wù)必用 EXPLAIN 分析,使用后務(wù)必驗(yàn)證性能。

到此這篇關(guān)于MySQL強(qiáng)制索引中USE/FORCE INDEX用法與避坑的文章就介紹到這了,更多相關(guān)MySQL強(qiáng)制索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL中修改表結(jié)構(gòu)時(shí)需要注意的一些地方

    MySQL中修改表結(jié)構(gòu)時(shí)需要注意的一些地方

    這篇文章主要介紹了MySQL中修改表結(jié)構(gòu)時(shí)需要注意的一些地方,作者援引Percona的相關(guān)的說(shuō)明來(lái)講述如何避免相關(guān)操作導(dǎo)致表無(wú)法使用的問(wèn)題,一些需要的朋友可以參考下
    2015-06-06
  • Mysql中JSON字段的值的實(shí)現(xiàn)示例

    Mysql中JSON字段的值的實(shí)現(xiàn)示例

    本文中介紹了如何通過(guò)SQL語(yǔ)句查詢JSON字段中的特定數(shù)據(jù),如查詢數(shù)組中的元素,提取映射中的值,以及使用不同的JSON函數(shù)來(lái)處理數(shù)據(jù),感興趣的可以了解一下
    2024-09-09
  • 通過(guò)代碼實(shí)例了解頁(yè)面置換算法原理

    通過(guò)代碼實(shí)例了解頁(yè)面置換算法原理

    這篇文章主要介紹了通過(guò)代碼實(shí)例了解頁(yè)面置換算法原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • mysql全文搜索 sql命令的寫法

    mysql全文搜索 sql命令的寫法

    首先,大家先去下載一份dvbbs.php beta1的代碼,解壓后先拋開(kāi)php代碼,找出你的mysql手冊(cè),如果沒(méi)有手冊(cè)那么就直接看下面的實(shí)例操作吧!
    2011-01-01
  • MySQL實(shí)戰(zhàn)之Insert語(yǔ)句的使用心得

    MySQL實(shí)戰(zhàn)之Insert語(yǔ)句的使用心得

    這篇文章主要給大家介紹了關(guān)于MySQL實(shí)戰(zhàn)之Insert語(yǔ)句的使用心得的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • MySQL?5.5,?5.6,?5.7,?8.0?特性對(duì)比

    MySQL?5.5,?5.6,?5.7,?8.0?特性對(duì)比

    MySQL是一個(gè)廣泛使用的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),你知道各個(gè)版本之前的區(qū)別嗎,本文主要介紹了MySQL?5.5,?5.6,?5.7,?8.0?特性對(duì)比,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • Linux安裝mysql并配置外網(wǎng)訪問(wèn)的實(shí)例

    Linux安裝mysql并配置外網(wǎng)訪問(wèn)的實(shí)例

    今天小編就為大家分享一篇Linux安裝mysql并配置外網(wǎng)訪問(wèn)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • mysql數(shù)據(jù)庫(kù)基本語(yǔ)法及操作大全

    mysql數(shù)據(jù)庫(kù)基本語(yǔ)法及操作大全

    這篇文章主要介紹了mysql數(shù)據(jù)庫(kù)基本語(yǔ)法及操作大全,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • MySQL GROUP_CONCAT限制解決方案

    MySQL GROUP_CONCAT限制解決方案

    這篇文章主要介紹了MySQL GROUP_CONCAT限制解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值
    2020-09-09
  • MySQL系列之八 MySQL服務(wù)器變量

    MySQL系列之八 MySQL服務(wù)器變量

    其中有些參數(shù)支持運(yùn)行時(shí)修改,會(huì)立即生效;有些參數(shù)不支持,且只能通過(guò)修改配置文件,并重啟服務(wù)器程序生效;有些參數(shù)作用域是全局的,且不可改變;有些可以為每個(gè)用戶提供單獨(dú)(會(huì)話)的設(shè)置
    2021-07-07

最新評(píng)論

安多县| 成安县| 拉孜县| 宜春市| 峨山| 磴口县| 大邑县| 剑川县| 板桥市| 武川县| 山阴县| 响水县| 公主岭市| 东港市| 静海县| 军事| 湄潭县| 四川省| 抚宁县| 花垣县| 准格尔旗| 凤庆县| 四子王旗| 逊克县| 台中市| 宣汉县| 鱼台县| 长宁区| 钦州市| 会泽县| 耿马| 芦溪县| 靖边县| 麦盖提县| 安泽县| 巴彦县| 峨眉山市| 宣城市| 贵德县| 沧州市| 宜川县|