mysql索引失效的幾種情況

一、索引失效的七種情況

在討論mysql索引失效的幾種情況之前,首先需要了解索引失效的七種情況。這七種情況包括:

1、全值匹配未使用索引

SELECT * FROM `users` WHERE `name` = 'John'

上面這個例子中,如果用戶表的name欄位沒有建立索引,那麼查詢將會全表掃描,導致索引失效。

2、最左前綴原則被破壞

SELECT * FROM `users` WHERE `name` LIKE '%John%'

上面這個例子中,如果用戶表的name欄位建立了索引,但是like操作中使用了通配符,那麼只有最左前綴能夠匹配,索引會失效。

3、範圍查詢左側未使用索引

SELECT * FROM `users` WHERE `age` > 20

上面這個例子中,如果用戶表的age欄位建立了索引,但是使用了大於號(或小於號),那麼左側的索引將不會被使用,導致索引失效。

4、使用函數或表達式索引失效

SELECT * FROM `users` WHERE YEAR(create_time) = 2021;

上面這個例子中,如果用戶表的create_time欄位建立了索引,但是在查詢中使用了函數或表達式(如YEAR函數),那麼索引將不會被使用,導致索引失效。

5、索引列上有計算

SELECT * FROM `users` WHERE `age` * 2 = 40

上面這個例子中,如果用戶表的age欄位建立了索引,但是在查詢中使用了計算(如乘以2),那麼索引將不會被使用,導致索引失效。

6、不同類型之間的比較

SELECT * FROM `users` WHERE `age` = '20'

上面這個例子中,如果用戶表的age欄位是integer類型,但是在查詢中使用了字元串類型(如’20’),那麼索引將不會被使用,導致索引失效。

7、索引需要被強制類型轉換

SELECT * FROM `users` WHERE CAST(`age` AS CHAR) = '20'

上面這個例子中,如果用戶表的age欄位是integer類型,但是在查詢中使用了char類型,那麼索引將不會被使用,導致索引失效。

二、mysql索引失效的情況

在理解索引失效的七種情況的基礎上,我們可以來看一些mysql索引失效的情況。

1、全文檢索

mysql提供了全文檢索(FULLTEXT)功能,但是全文檢索不支持LIKE、通配符、正則等操作,因此如果使用了這些操作,就會導致索引失效。

SELECT * FROM `articles` WHERE MATCH(`title`) AGAINST('hello mysql' IN NATURAL LANGUAGE MODE);

2、聯合索引未使用最左前綴

在使用聯合索引時,需要注意最左前綴原則。如果不是按照最左前綴的順序使用索引,那麼將會導致索引失效。

SELECT * FROM `users` WHERE `name` = 'John' AND `age` = 20;

上面這個例子中,如果用戶表使用了聯合索引(name, age),但是查詢時只使用了name欄位,那麼age欄位的索引將不會被使用,導致索引失效。

3、多表關聯查詢

在進行多表關聯查詢時,如果其中一張表沒有建立索引,那麼將會導致索引失效。

SELECT `users`.`name`, `articles`.`title` FROM `users` JOIN `articles` ON `users`.`id` = `articles`.`user_id` WHERE `users`.`name` = 'John';

上面這個例子中,如果用戶表(users)的name欄位有索引,但是文章表(articles)的user_id欄位沒有索引,那麼查詢將會進行全表掃描,導致索引失效。

三、mysql中索引失效的情況

除了上面提到的情況外,還有一些特殊情況也會導致mysql中索引失效。

1、欄位類型

在mysql中,欄位類型對於索引的使用非常重要。如果使用了不合適的欄位類型,那麼會導致索引失效。

例如,將字元串類型的欄位作為聯合索引的第一項,將會比整數類型的欄位慢很多。

2、數據分布的不均勻

如果數據分布不均勻,那麼索引失效的可能性將會增加。

例如,當一個表中有大量的相同數據時,如所有用戶的性別都是男性,那麼查詢性別為女性的記錄將會導致索引失效,因為大部分數據都是男性。

3、表中數據量很少

如果表中的數據量非常少,那麼索引失效的可能性也會增加。

這是因為當數據量很少時,全表掃描的代價非常小,因此mysql可能會選擇進行全表掃描而不是使用索引。

四、mysql的索引失效選取

為了避免索引失效,需要合理地選取索引。以下是一些選取索引的方法。

1、聯合索引

在使用聯合索引時,需要按照最左前綴的順序使用索引。

例如,對於聯合索引(name, age),如果只查詢name欄位,那麼age欄位的索引將不會被使用,因為它不是最左前綴。

2、優先選擇前綴索引

如果只需要匹配字元串的前綴,那麼建立前綴索引可能會更加高效。

ALTER TABLE `users` ADD INDEX `name` (`name`(10));

上面這個例子中,為name欄位建立長度為10的前綴索引。

3、擴展索引的使用範圍

如果一個索引可以被多個查詢所使用,那麼可以考慮對這個索引進行擴展,以便可以更加高效地使用。

例如,對於索引(name, age),如果查詢中只使用了name欄位,那麼可以將age欄位加入到索引中,以便在查詢時可以更加高效地使用索引。

ALTER TABLE `users` ADD INDEX `name_age` (`name`, `age`);

4、避免使用函數或表達式

在查詢時,盡量避免使用函數或表達式。如果必須使用,可以考慮將函數或表達式的結果存儲到另一個欄位中,以便可以使用索引。

5、避免使用大範圍的範圍查詢

在進行範圍查詢時,盡量避免大範圍的範圍查詢。如果必須使用,可以對被查詢的欄位建立單獨的索引。

6、注意選擇合適的欄位類型

在創建表時,需要注意選擇合適的欄位類型。如果選擇不合適的欄位類型,那麼可能會導致索引失效。

例如,在使用字元串類型時,需要注意字符集、長度等因素。

7、數據分布均勻

為了避免索引失效,需要保證數據的分布均勻。如果數據分布不均勻,可以考慮將數據拆分到多個表中,或者使用分區表來避免數據傾斜。

8、避免多表關聯查詢

在進行多表關聯查詢時,需要注意多表關聯的複雜度。如果關聯的表比較多,或者關聯的表中有表沒有建立索引,那麼將會導致索引失效。

因此,需要盡量避免多表關聯查詢,或者將多表關聯查詢拆分成多次的單表查詢。

總結

在mysql中,索引是優化查詢性能的重要手段。然而,如果使用不當,也會導致索引失效,進而降低查詢性能。因此,在創建索引時需要注意選取合適的欄位、遵守最左前綴原則、避免大範圍的範圍查詢、避免使用函數或表達式、保證數據分布均勻等因素。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/258235.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-15 12:48
下一篇 2024-12-15 12:48

相關推薦

  • 如何修改mysql的埠號

    本文將介紹如何修改mysql的埠號,方便開發者根據實際需求配置對應埠號。 一、為什麼需要修改mysql埠號 默認情況下,mysql使用的埠號是3306。在某些情況下,我們需…

    編程 2025-04-29
  • Python基本索引用法介紹

    Python基本索引是指通過下標來獲取列表、元組、字元串等數據類型中的元素。下面將從多個方面對Python基本索引進行詳細的闡述。 一、列表(List)的基本索引 列表是Pytho…

    編程 2025-04-29
  • 如何將Oracle索引變成另一個表?

    如果你需要將一個Oracle索引導入到另一個表中,可以按照以下步驟來完成這個過程。 一、創建目標表 首先,需要在資料庫中創建一個新的表格,用來存放索引數據。可以通過以下代碼創建一個…

    編程 2025-04-29
  • Python操作MySQL

    本文將從以下幾個方面對Python操作MySQL進行詳細闡述: 一、連接MySQL資料庫 在使用Python操作MySQL之前,我們需要先連接MySQL資料庫。在Python中,我…

    編程 2025-04-29
  • 索引abc,bc會走索引嗎

    答案是:取決於MySQL版本和表結構 一、MySQL版本的影響 在MySQL 5.6之前的版本中,MySQL會同時使用abc和bc索引。但在MySQL 5.6及之後的版本中,MyS…

    編程 2025-04-29
  • Python數據類型分為哪幾種

    Python作為一門非常靈活的編程語言,有著非常豐富的數據類型。Python的數據類型可以分為數字類型、字元串類型、列表類型、元組類型、字典類型和集合類型六種。 一、數字類型 Py…

    編程 2025-04-29
  • MySQL遞歸函數的用法

    本文將從多個方面對MySQL遞歸函數的用法做詳細的闡述,包括函數的定義、使用方法、示例及注意事項。 一、遞歸函數的定義 遞歸函數是指在函數內部調用自身的函數。MySQL提供了CRE…

    編程 2025-04-29
  • Python切片索引越界是否會報錯

    解答:當對一個字元串、列表、元組進行切片時,如果索引越界會返回空序列,不會報錯。 一、切片索引的概念 切片是指對序列進行操作,從其中一段截取一個新序列。序列可以是字元串、列表、元組…

    編程 2025-04-29
  • Python數組索引位置用法介紹

    Python是一門多用途的編程語言,它有著非常強大的數據處理能力。數組是其中一個非常重要的數據類型之一。Python支持多種方式來操作數組的索引位置,我們可以從以下幾個方面對Pyt…

    編程 2025-04-28
  • MySQL bigint與long的區別

    本文將從數據類型定義、存儲空間、數據範圍、計算效率、應用場景五個方面詳細闡述MySQL bigint與long的區別。 一、數據類型定義 bigint在MySQL中是一種有符號的整…

    編程 2025-04-28

發表回復

登錄後才能評論