2017-08-04 63 views
0

這裏是我的查詢:爲什麼我的查詢不使用任何索引?

select u.*, 
     concat(user_fname, ' ', user_lname) like concat(?, '%') `both`, 
     user_lname like ? last_name 
from users u 
where concat(user_fname, ' ', user_lname) like concat(?, '%') 
    or user_lname like concat(?, '%') 
order by `both`*2 DESC, last_name 

而且我有兩個指標:users(user_fname,user_lname)users(user_lname)

這裏是EXPLAIN結果:

id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra 
1 | SIMPLE  | u  | ALL | user_lname | NULL | NULL | NULL | 9 | Using where 

看到了嗎?它不使用任何索引。爲什麼?以及如何使查詢最佳?

+3

您正在使用函數的結果。索引(如果有的話)是基於列值而不是函數的結果。 – Hogan

+0

這個'concat(user_fname,',user_lname)like concat(?,'%')' –

+0

要了解更多關於索引檢查的知識:MySQL index [** TIPS **](http://mysql.rjweb.org/ doc.php/index_cookbook_mysql)這個網站http://use-the-index-luke.com/和這個視頻.https://www.youtube.com/watch?v = ELR7-RdU9XU&index = 53&list = WL –

回答

2
  • 不要隱藏一個函數調用(CONCAT)內的索引列,
  • OR是致命的優化,
  • 領先通配符(%)使得LIKE無法使用索引,
  • 由於您正在獲取所有列,因此擁有「覆蓋」索引是不切實際的。
  • 在某些情況下,可以使用ORDER BY的索引而不是WHERE。但是你有ASC和DESC的混合,所以這是不可能的(直到8.0版本)。

方案A:在字段上使用FULLTEXT和MATCH。 (對FULLTEXT有限制,可能會導致無法使用。)

計劃B:有多列連接的列並對其執行單個LIKE。 (這並不能解決所有問題。)

底線:索引是非常有效的if if you live within their constraints。您的查詢違反了很多限制,我認爲查詢沒有任何希望;它必須執行表掃描。

警告:可能會有更多的問題。

相關問題