2017-08-04 84 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。您的查询违反了很多限制,我认为查询没有任何希望;它必须执行表扫描。

警告:可能会有更多的问题。

相关问题