成人免费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

2019-11-07 21:17:07

數字化轉型公司

2020-08-10 11:20:59

索引MySQL數據庫

2022-07-12 09:36:18

數據庫查詢

2021-04-08 20:50:17

創建索引MySQL

2021-04-08 11:15:55

索引數據庫MySQL

2025-06-26 08:12:11

2019-05-13 15:41:49

AI人工智能體驗

2013-07-09 13:52:31

程序員Android

2022-09-20 10:22:00

CIOIT業務管理者

2016-03-17 16:57:39

SaaSSaaS公司指標

2023-04-24 08:11:02

圖片alt語音

2022-05-11 09:04:50

Go函數數組

2022-05-05 12:02:45

SCSS函數開發

2020-03-05 11:10:18

Left join數據庫MySQL

2010-05-24 09:11:13

Facebook隱私政策

2022-10-17 07:40:21

AI項目數據

2022-06-23 12:52:53

數據庫方案
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久国内精品 | 拍真实国产伦偷精品 | 久久久久无码国产精品一区 | www久久国产 | 精品国产欧美一区二区三区成人 | 在线国产一区二区 | caoporn视频| 在线观看欧美一区 | 久久久91精品国产一区二区三区 | 国产精品伦一区二区三级视频 | 精品一区电影 | 亚洲精品在线播放 | 欧美日韩精品一区二区三区四区 | 免费黄色片视频 | 九九成人| av免费网| 国产一区二区av | 日本欧美大片 | 在线免费观看黄视频 | 一级黄在线观看 | 黄色av网站在线观看 | 久久久久久亚洲精品 | 成人国产精品免费观看 | 亚洲精品自在在线观看 | 精品国产一区二区三区久久 | 美日韩一区二区 | 日韩视频国产 | 黄色毛片黄色毛片 | 欧美精品1区2区3区 精品国产欧美一区二区 | 久久久www成人免费无遮挡大片 | 不卡的av在线 | 国产最新视频在线 | 男女网站免费观看 | 在线观看成人小视频 | 日韩精品免费在线 | 亚洲国产成人精品女人久久久 | 一区中文字幕 | 天天操天天插天天干 | 欧美午夜精品久久久久久浪潮 | 9191成人精品久久 | 日本午夜视频 |