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

創建了索引查詢還是慢,你可能犯了這些錯誤

運維 數據庫運維
最左原則也就是需要從左到右的使用索引中的字段,一條 SQL 語句可以只使用聯合索引的一部分,但是需要從最左側開始,否則也會失效。

[[405189]]

本文轉載自微信公眾號「碼上Java」,作者msJava。轉載本文請聯系碼上Java公眾號。

1. 如果索引進行了表達式計算,會失效

我們可以使用EXPLAIN關鍵字來查看 MySQL 中一條 SQL 語句的執行計劃,比如:

  1. EXPLAIN SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_id+1 = 900001 

運行結果:

  1. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 
  2. | id | select_type | table           | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       | 
  3. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 
  4. |  1 | SIMPLE      | product_comment | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 996663 |   100.00 | Using where | 
  5. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 

你能看到如果對索引進行了表達式計算,索引就失效了。這是因為我們需要把索引字段的取值都取出來,然后依次進行表達式的計算來進行條件判斷,因此采用的就是全表掃描的方式,運行時間也會慢很多,最終運行時間為 2.538 秒。

為了避免索引失效,我們對 SQL 進行重寫:

  1. SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_id = 900000 

運行時間為 0.039 秒。

2. 如果對索引使用函數,會失效

比如我們想要對 comment_text 的前三位為 abc 的內容進行條件篩選,這里我們來查看下執行計劃:

  1. EXPLAIN SELECT comment_id, user_id, comment_text FROM product_comment WHERE SUBSTRING(comment_text, 1,3)='abc' 

運行結果:

  1. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 
  2. | id | select_type | table           | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       | 
  3. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 
  4. |  1 | SIMPLE      | product_comment | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 996663 |   100.00 | Using where | 
  5. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 

你能看到對索引字段進行函數操作,造成了索引失效,這時可以進行查詢重寫:

  1. SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_text LIKE 'abc%' 

使用 EXPLAIN 對查詢語句進行分析:

  1. +----+-------------+-----------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+ 
  2. | id | select_type | table           | partitions | type  | possible_keys | key          | key_len | ref  | rows | filtered | Extra                 | 
  3. +----+-------------+-----------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+ 
  4. |  1 | SIMPLE      | product_comment | NULL       | range | comment_text  | comment_text | 767     | NULL |  213 |   100.00 | Using index condition | 
  5. +----+-------------+-----------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+ 

你能看到經過查詢重寫后,可以使用索引進行范圍檢索,從而提升查詢效率。

3. 在 WHERE 子句中,如果在 OR 前的條件列進行了索引,而在 OR 后的條件列沒有進行索引,會失效。

比如下面的 SQL 語句,comment_id 是主鍵,而 comment_text 沒有進行索引,因為 OR 的含義就是兩個只要滿足一個即可,因此只有一個條件列進行了索引是沒有意義的,只要有條件列沒有進行索引,就會進行全表掃描,因此索引的條件列也會失效:

  1. EXPLAIN SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_id = 900001 OR comment_text = '462eed7ac6e791292a79' 

運行結果:

  1. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 
  2. | id | select_type | table           | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       | 
  3. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 
  4. |  1 | SIMPLE      | product_comment | NULL       | ALL  | PRIMARY       | NULL | NULL    | NULL | 996663 |    10.00 | Using where | 
  5. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 

如果我們把 comment_text 創建了索引會是怎樣的呢?

  1. +----+-------------+-----------------+------------+-------------+----------------------+----------------------+---------+------+------+----------+------------------------------------------------+ 
  2. | id | select_type | table           | partitions | type        | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra                                          | 
  3. +----+-------------+-----------------+------------+-------------+----------------------+----------------------+---------+------+------+----------+------------------------------------------------+ 
  4. |  1 | SIMPLE      | product_comment | NULL       | index_merge | PRIMARY,comment_text | PRIMARY,comment_text | 4,767   | NULL |    2 |   100.00 | Using union(PRIMARY,comment_text); Using where | 
  5. +----+-------------+-----------------+------------+-------------+----------------------+----------------------+---------+------+------+----------+------------------------------------------------+ 

你能看到這里使用到了 index merge,簡單來說 index merge 就是對 comment_id 和 comment_text 分別進行了掃描,然后將這兩個結果集進行了合并。這樣做的好處就是避免了全表掃描。

4. 當我們使用 LIKE 進行模糊查詢的時候,后面不能是 %,會失效。

  1. EXPLAIN SELECT comment_id, user_id, comment_text FROM product_comment WHERE comment_text LIKE '%abc' 

運行結果:

  1. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 
  2. | id | select_type | table           | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       | 
  3. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 
  4. |  1 | SIMPLE      | product_comment | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 996663 |    11.11 | Using where | 
  5. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 

這個很好理解,如果一本字典按照字母順序進行排序,我們會從首位開始進行匹配,而不會對中間位置進行匹配,否則索引就失效了。

5. 索引列與 NULL 或者 NOT NULL 進行判斷的時候會失效。

這是因為索引并不存儲空值,所以最好在設計數據表的時候就將字段設置為 NOT NULL 約束,比如你可以將 INT 類型的字段,默認值設置為 0。將字符類型的默認值設置為空字符串 (’’)。

總結

除了以上情況索引會失效,我們在使用聯合索引的時候要注意最左原則。 

最左原則也就是需要從左到右的使用索引中的字段,一條 SQL 語句可以只使用聯合索引的一部分,但是需要從最左側開始,否則也會失效。

 

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

2020-07-01 07:38:38

SQL數據庫程序員

2020-10-29 09:19:11

索引查詢存儲

2020-03-05 16:55:56

索引數據庫SQL

2020-08-10 11:20:59

索引MySQL數據庫

2019-11-07 21:17:07

數字化轉型公司

2022-07-12 09:36:18

數據庫查詢

2021-04-08 11:15:55

索引數據庫MySQL

2021-04-08 20:50:17

創建索引MySQL

2019-05-13 15:41:49

AI人工智能體驗

2013-07-09 13:52:31

程序員Android

2023-04-24 08:11:02

圖片alt語音

2025-06-26 08:12:11

2022-05-11 09:04:50

Go函數數組

2022-05-05 12:02:45

SCSS函數開發

2020-03-05 11:10:18

Left join數據庫MySQL

2022-06-23 12:52:53

數據庫方案

2016-03-17 16:57:39

SaaSSaaS公司指標

2022-10-17 07:40:21

AI項目數據

2022-09-20 10:22:00

CIOIT業務管理者

2024-02-17 08:00:00

內部威脅濫用數據網絡安全
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91免费观看 | 国产重口老太伦 | 成人影 | 二区欧美 | 精彩视频一区二区三区 | 91一区二区| 亚洲成人播放器 | 在线播放一区 | 九九综合| 亚洲成av人影片在线观看 | 黄视频免费观看 | 日韩和的一区二在线 | 中文字幕av网 | 久久男人 | 日韩欧美国产精品一区二区 | 亚洲视频一区二区三区 | 欧美电影网 | xxxxx免费视频 | 中文字幕视频在线 | 久久性av| 国产乱码高清区二区三区在线 | 国产在线观看网站 | 午夜羞羞 | 在线国产一区 | 户外露出一区二区三区 | 亚洲一区二区在线播放 | 日本在线一区二区 | 久久久久免费精品国产小说色大师 | 亚洲电影一区二区三区 | 国产成人精品免高潮在线观看 | 亚洲综合在线播放 | 精品免费国产一区二区三区四区 | 密桃av | 欧美久久大片 | 午夜av影院 | 日本在线看 | 久久精品福利 | 国产高清一区 | 人人干在线视频 | 性一交一乱一透一a级 | 欧美视频三区 |