自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

創(chuàng)建了索引查詢還是慢,你可能犯了這些錯誤

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

[[405189]]

本文轉(zhuǎn)載自微信公眾號「碼上Java」,作者msJava。轉(zhuǎn)載本文請聯(lián)系碼上Java公眾號。

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

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

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

運行結(jié)果:

  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. 如果對索引使用函數(shù),會失效

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

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

運行結(jié)果:

  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. +----+-------------+-----------------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 

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

  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. +----+-------------+-----------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+ 

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

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' 

運行結(jié)果:

  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 創(chuàng)建了索引會是怎樣的呢?

  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 分別進行了掃描,然后將這兩個結(jié)果集進行了合并。這樣做的好處就是避免了全表掃描。

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

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

運行結(jié)果:

  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 進行判斷的時候會失效。

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

總結(jié)

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

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

 

責任編輯:武曉燕 來源: 碼上Java
相關(guān)推薦

2020-07-01 07:38:38

SQL數(shù)據(jù)庫程序員

2020-10-29 09:19:11

索引查詢存儲

2020-03-05 16:55:56

索引數(shù)據(jù)庫SQL

2019-11-07 21:17:07

數(shù)字化轉(zhuǎn)型公司

2020-08-10 11:20:59

索引MySQL數(shù)據(jù)庫

2022-07-12 09:36:18

數(shù)據(jù)庫查詢

2021-04-08 20:50:17

創(chuàng)建索引MySQL

2021-04-08 11:15:55

索引數(shù)據(jù)庫MySQL

2019-05-13 15:41:49

AI人工智能體驗

2013-07-09 13:52:31

程序員Android

2022-09-20 10:22:00

CIOIT業(yè)務管理者

2016-03-17 16:57:39

SaaSSaaS公司指標

2023-04-24 08:11:02

圖片alt語音

2022-05-11 09:04:50

Go函數(shù)數(shù)組

2022-06-23 12:52:53

數(shù)據(jù)庫方案

2010-05-24 09:11:13

Facebook隱私政策

2020-03-05 11:10:18

Left join數(shù)據(jù)庫MySQL

2022-05-05 12:02:45

SCSS函數(shù)開發(fā)

2022-10-17 07:40:21

AI項目數(shù)據(jù)

2023-07-14 07:05:27

優(yōu)化首席信息官IT
點贊
收藏

51CTO技術(shù)棧公眾號