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