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。