成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL用了函數到底會不會導致索引失效

數據庫 MySQL
MySQL 8.0 引入了功能索引(Functional Indexes)的新特性,這種索引允許在創建時包含列上的表達式。這意味著可以對數據進行計算或轉換,并針對結果建立索引。即使在查詢中使用了函數操作,也可以利用這些索引來優化查詢性能。

本次主要聊一聊關于函數到底會不會導致索引失效呢?

很多人認為,在使用函數后就無法使用索引。

這主要是因為索引是按照列值的原始順序組織和存儲的。當對列應用函數時(如數學運算、字符串操作或日期函數等),函數會改變原始數據的值或格式,使得數據庫無法直接定位到這些經過函數轉換后的值。因此,數據庫不得不執行全表掃描,以確保能夠評估所有行上的函數操作,這導致查詢性能下降。

在 MySQL 8.0 之后,引入了函數索引,這改變了以往對函數使用索引的限制。

MySQL 8.0 引入了功能索引(Functional Indexes)的新特性,這種索引允許在創建時包含列上的表達式。這意味著可以對數據進行計算或轉換,并針對結果建立索引。即使在查詢中使用了函數操作,也可以利用這些索引來優化查詢性能。

功能索引不是直接在表的列上創建的,而是基于列的某個表達式創建的。這個表達式可以是簡單的數學運算,也可以是字符串函數、日期函數等。一旦創建了功能索引,MySQL 在執行涉及該表達式的查詢時能夠使用這個索引,從而提升查詢效率。

使用方式

在 MySQL 8.0 中,您可以創建一個基于 first_name 和 last_name 合并后的表達式的功能索引,示例如下:

CREATE INDEX full_name_index ON employees ((CONCAT(first_name, ' ', last_name)));

這個例子中,我們使用了 CONCAT 函數將 first_name 和 last_name 合并成一個全名,并在創建索引時使用了這個表達式 (CONCAT(first_name, ' ', last_name))。這樣一來,即使在查詢中直接使用全名的合并結果,MySQL 也能夠利用 full_name_index 索引來優化查詢性能。

SELECT * FROM employees WHERE CONCAT(first_name, ' ', last_name) = 'Pai daxing';

圖片圖片

如上圖所示,執行計劃顯示我們成功利用了 idx_full_name索引!

因此,即使在查詢的 WHERE 子句中使用了 CONCAT 函數,我們依然能夠充分利用 idx_full_name 函數索引,從而有效提升了查詢的效率。

注意事項

函數索引雖然能夠顯著提高涉及索引表達式的查詢性能,但其創建可能增加數據插入、更新和刪除的成本,因為數據庫需要維護更多的索引數據。因此,在創建函數索引時需要謹慎,不能盲目使用。

使用函數索引時,必須仔細考慮和測試,以確保性能提升符合預期。

此外,在創建函數索引時,需要確保表達式是確定的,即對于給定的輸入值始終產生相同的輸出值。非確定性表達式不適合用于函數索引。

常見函數索引用法

給大家列舉一些常見的函數索引的使用。

字符串處理

當您經常需要根據某個字符串列的某部分進行查詢時,可以考慮使用函數索引。例如,如果您希望根據郵箱地址的域名部分查詢用戶,可以創建如下的函數索引:

CREATE INDEX idx_email_domain ON users ((SUBSTRING_INDEX(email, '@', -1)));

這樣,當您查詢特定域名的郵箱時(例如 qq 郵箱),可以利用這個索引:

SELECT * FROM users WHERE SUBSTRING_INDEX(email, '@', -1) = 'qq.com';

日期和時間處理

對于涉及日期和時間處理的查詢,函數索引也非常有用。假設您需要頻繁查詢基于訂單日期的年份或月份,可以創建如下的索引:

CREATE INDEX idx_order_year ON orders ((YEAR(order_date)));
CREATE INDEX idx_order_month ON orders ((MONTH(order_date)));

這允許您高效地查詢特定年份或月份的訂單:

SELECT * FROM orders WHERE YEAR(order_date) = 2022;
SELECT * FROM orders WHERE MONTH(order_date) = 12;

數學運算

如果查詢條件經常包含對數值列的數學運算,可以針對這些運算創建函數索引。例如,如果您希望根據產品折扣后的價格進行查詢,可以創建如下索引:

CREATE INDEX idx_discounted_price ON products ((price * (1 - discount_rate)));

然后,您可以高效地查詢特定范圍的折扣價格:

SELECT * FROM products WHERE price * (1 - discount_rate) BETWEEN 50 AND 100;

使用 JSON 函數

如果在 MySQL 中使用 JSON 數據類型,并且需要基于 JSON 屬性進行查詢,可以創建基于 JSON 函數的索引。例如,如果您有一個存儲 JSON 數據的列,并且希望根據 JSON 文檔中的某個鍵進行查詢,可以創建如下索引:

CREATE INDEX idx_json_key ON orders ((JSON_UNQUOTE(JSON_EXTRACT(order_info, '$.status'))));

這樣,您可以高效地查詢具有特定狀態的訂單:

SELECT * FROM orders WHERE JSON_UNQUOTE(JSON_EXTRACT(order_info, '$.status')) = 'shipped';

大小寫不敏感的搜索

如果您需要執行大小寫不敏感的字符串搜索,可以創建一個基于 LOWER() 或 UPPER() 函數的索引:

CREATE INDEX idx_lower_case_name ON customers ((LOWER(name)));

這樣可以讓您執行大小寫不敏感的搜索,同時不影響性能:

SELECT * FROM customers WHERE LOWER(name) = LOWER('John Doe');

在使用函數索引時,需要權衡索引的維護成本和性能提升。雖然函數索引可以顯著提升特定查詢的性能,但它們也會增加插入、更新和刪除操作的成本,因為數據庫需要維護更多的索引數據。因此,在實際應用中,建議僅對那些經常作為查詢條件的列和表達式創建函數索引。

責任編輯:武曉燕 來源: 碼上遇見你
相關推薦

2020-09-29 08:33:17

基站信號健康

2022-04-20 11:41:45

Kafka數據解決方案

2021-09-21 16:18:07

手機電池快充

2020-11-13 07:14:55

Kafka消息中間件

2024-10-08 09:35:23

2020-07-20 15:20:44

ThreadLocalJava多線程

2020-12-08 09:45:07

MySQL數據庫索引

2019-01-21 16:54:24

車聯網智能手機系統iOS

2012-04-16 15:05:39

數據壟斷互聯網

2022-06-27 07:23:44

MySQL常量優化

2020-09-29 11:33:11

5G

2024-05-31 13:04:09

2024-06-03 00:00:01

索引MySQL技術

2012-07-13 16:29:30

2024-12-11 08:09:54

2024-11-18 08:03:30

Java多次啟動線程

2012-12-18 12:55:45

2024-12-20 07:30:00

2023-02-11 08:18:15

AI人工智能ChatGPT

2021-02-07 18:07:28

大數據AI人工智能
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本在线一区二区三区 | 一区欧美| 亚洲自拍偷拍免费视频 | 精品国产精品国产偷麻豆 | 国产高清视频在线 | 中文av电影 | 欧美日韩成人在线 | 国产精品久久久久久久久久 | 久久久精品视频免费看 | 久久99精品久久久久婷婷 | 国产精品a一区二区三区网址 | 本地毛片 | 一级毛片视频 | 亚洲一区免费视频 | 亚洲欧美日韩精品久久亚洲区 | 91精品综合久久久久久五月天 | 国产精品1区2区 | 欧美色性 | 亚洲欧美成人 | 欧美精品二区 | 中文字幕 在线观看 | 色av一区| 国产69精品久久99不卡免费版 | 午夜三级在线观看 | 亚州激情| 99久久久久 | 亚洲一区二区三区在线播放 | 成年网站在线观看 | 亚洲精品国产一区 | 欧美中文字幕在线 | 国产日韩欧美二区 | 在线一级片 | 欧美一级淫片免费视频黄 | 久久青| 日韩另类视频 | 中文字幕亚洲视频 | 日本免费黄色一级片 | 久久久999成人 | 国产欧美精品一区二区色综合 | 成人午夜免费网站 | 国产精品久久久久av |