MySQL force index强制走索引注意了吗?


1.MySQL版本: Percona Server 5.6.25 

  1 --使用USE INDEX
  2 mysql> DESC UPDATE  ItemPrice0016 USE INDEX (idx_itemId) SET updated=unix_timestamp(now()),endTime=unix_timestamp(now()) WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0 AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime LIMIT 5000\G
  3 *************************** 1. row ***************************
  4            id: 1
  5   select_type: SIMPLE
  6         table: ItemPrice0016
  7          type: range
  8 possible_keys: idx_itemId_skuId
  9           key: idx_itemId_skuId
 10       key_len: 8
 11           ref: const
 12          rows: 5068
 13         Extra: Using where; Using temporary
 14 1 row in set (0.00 sec)
 15 
 16 --使用FORCE INDEX
 17 mysql> DESC UPDATE
 18     -> ItemPrice0016 FORCE INDEX (idx_itemId)
 19     -> SET updated=unix_timestamp(now()),endTime=unix_timestamp(now())
 20     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0
 21     -> AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
 22     -> LIMIT 5000\G
 23 *************************** 1. row ***************************
 24            id: 1
 25   select_type: SIMPLE
 26         table: ItemPrice0016
 27          type: range
 28 possible_keys: idx_itemId_skuId
 29           key: idx_itemId_skuId
 30       key_len: 8
 31           ref: const
 32          rows: 5068
 33         Extra: Using where; Using temporary
 34 1 row in set (0.01 sec)
 35 --发现真实走的索引是:idx_itemId_skuId , USE INDEX|FORCE INDEX 都没报错,这就不是很确定了,于是开始了下面的验证:
 36 
 37 mysql> DESC UPDATE
 38     -> ItemPrice0016 FORCE INDEX (idx_itemId_)
 39     -> SET updated=unix_timestamp(now()),endTime=unix_timestamp(now())
 40     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0
 41     -> AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
 42     -> LIMIT 5000\G
 43 *************************** 1. row ***************************
 44            id: 1
 45   select_type: SIMPLE
 46         table: ItemPrice0016
 47          type: range
 48 possible_keys: idx_itemId_skuId
 49           key: idx_itemId_skuId
 50       key_len: 8
 51           ref: const
 52          rows: 5068
 53         Extra: Using where; Using temporary
 54 1 row in set (0.00 sec)
 55 
 56 mysql> DESC UPDATE
 57     -> ItemPrice0016 FORCE INDEX (idx_itemId_s)
 58     -> SET updated=unix_timestamp(now()),endTime=unix_timestamp(now())
 59     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0
 60     -> AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
 61     -> LIMIT 5000\G
 62 *************************** 1. row ***************************
 63            id: 1
 64   select_type: SIMPLE
 65         table: ItemPrice0016
 66          type: range
 67 possible_keys: idx_itemId_skuId
 68           key: idx_itemId_skuId
 69       key_len: 8
 70           ref: const
 71          rows: 5068
 72         Extra: Using where; Using temporary
 73 1 row in set (0.00 sec)
 74 
 75 mysql> DESC UPDATE
 76     -> ItemPrice0016 FORCE INDEX (idx_itemId_sk)
 77     -> SET updated=unix_timestamp(now()),endTime=unix_timestamp(now())
 78     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0
 79     -> AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
 80     -> LIMIT 5000\G
 81 *************************** 1. row ***************************
 82            id: 1
 83   select_type: SIMPLE
 84         table: ItemPrice0016
 85          type: range
 86 possible_keys: idx_itemId_skuId
 87           key: idx_itemId_skuId
 88       key_len: 8
 89           ref: const
 90          rows: 5068
 91         Extra: Using where; Using temporary
 92 1 row in set (0.00 sec)
 93 
 94 mysql> DESC UPDATE
 95     -> ItemPrice0016 FORCE INDEX (idx_itemId_sk2)
 96     -> SET updated=unix_timestamp(now()),endTime=unix_timestamp(now())
 97     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0
 98     -> AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
 99     -> LIMIT 5000\G
100 ERROR 1176 (42000): Key 'idx_itemId_sk2' doesn't exist in table 'ItemPrice0016'
101 
102 
103 mysql> DESC select *
104     -> from ItemPrice0016 FORCE INDEX (idx_itemId)
105     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0 AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
106     -> LIMIT 5000\G
107 *************************** 1. row ***************************
108            id: 1
109   select_type: SIMPLE
110         table: ItemPrice0016
111          type: ref
112 possible_keys: idx_itemId_skuId
113           key: idx_itemId_skuId
114       key_len: 8
115           ref: const
116          rows: 5068
117         Extra: Using where
118 1 row in set (0.00 sec)
119 
120 mysql> DESC select *
121     -> from ItemPrice0016 USE INDEX (idx_itemId)
122     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0 AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
123     -> LIMIT 5000\G
124 *************************** 1. row ***************************
125            id: 1
126   select_type: SIMPLE
127         table: ItemPrice0016
128          type: ref
129 possible_keys: idx_itemId_skuId
130           key: idx_itemId_skuId
131       key_len: 8
132           ref: const
133          rows: 5068
134         Extra: Using where
135 1 row in set (0.00 sec)
136 
137 mysql> DESC select *
138     -> from ItemPrice0016 USE INDEX (idx_itemId_s)
139     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0 AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
140     -> LIMIT 5000\G
141 *************************** 1. row ***************************
142            id: 1
143   select_type: SIMPLE
144         table: ItemPrice0016
145          type: ref
146 possible_keys: idx_itemId_skuId
147           key: idx_itemId_skuId
148       key_len: 8
149           ref: const
150          rows: 5068
151         Extra: Using where
152 1 row in set (0.01 sec)
153 
154 mysql> DESC select *
155     -> from ItemPrice0016 USE INDEX (idx_itemId_s3)
156     -> WHERE itemId=618692496 AND promotionId='700009162676' AND source in (-1, 2, 3) AND isDeleted = 0 AND endTime >= unix_timestamp(now()) AND unix_timestamp(now()) >= startTime
157     -> LIMIT 5000\G
158 ERROR 1176 (42000): Key 'idx_itemId_s3' doesn't exist in table 'ItemPrice0016'

总结:

1.USE INDEX| FORCE INDEX 都是最左匹配,只要匹配上最左前缀的索引是不会报错

2.隐患:如果USE INDEX| FORCE INDEX的原索引不存在,匹配到了其它索引,而其它索引并不是最优的,会导致性能问题,最好走那个索引就FORCE INDEX|USE INDEX 那个索引。

3.原则不使用USE INDEX| FORCE INDEX,除非其它方式搞不定,再不得不使用FORCE INDEX|USE INDEX。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM