例如,我有3列的表格: “id”,“a”,“b”
id是主键 a - 没有索引的字段 b - 没有索引的字段
CREATE TABLE samples (id INT, a INT, b INT, PRIMARY KEY(id));
现在我想做一个选择查询:
SELECT * FROM samples where a = '77345' and b = '234234';
据我所知,如果我有“a”和“b”字段的索引,这个查询会非常快,如下所示:
CREATE INDEX ab_index ON samples (a, b) USING BTREE;
问题:
如果我只添加“a”字段的索引(没有其他索引),上面的选择查询会更快:
CREATE INDEX a_index ON samples (a) USING BTREE;
如果是的话,会有多快?
答案 0 :(得分:1)
表格样本:
create table samples (id int NOT NULL AUTO_INCREMENT, a int, b int, PRIMARY KEY(id));
已插入 2,483,308 条记录
测试查询
select * from samples where a = 3434 and b = 4389;
没有索引:
**Timing (as measured by the server):**
Execution time: 0:00:0.57075288
Table lock wait time: 0:00:0.00008100
索引为(a):
CREATE INDEX a_index ON samples (a) USING BTREE;
**Timing (as measured by the server):**
Execution time: 0:00:0.00021302
Table lock wait time: 0:00:0.00008300
仅使用索引(a,b):
CREATE INDEX ab_index ON samples (a, b) USING BTREE;
**Timing (as measured by the server):**
Execution time: 0:00:0.00019394
Table lock wait time: 0:00:0.00007600
使用(a)和(a,b)索引:
**Timing (as measured by the server):**
Execution time: 0:00:0.00022304
Table lock wait time: 0:00:0.00008300
删除了索引,没有任何索引:
**Timing (as measured by the server):**
Execution time: 0:00:0.57105565
Table lock wait time: 0:00:0.00008300
使用(a)再次索引:
Execution time: 0:00:0.00021866
Table lock wait time: 0:00:0.00008700
是的,添加(a)只有索引会显着提高速度。
有什么奇怪的,解释说明在(a)和(a,b)索引存在的情况下,mySQL仍然因某种原因使用(a)索引。
explain select * from samples where a = 45 and b = 3456;
+ ---- + ------------- + --------- + ------ + ---------- -------- + --------- + --------- + ------- + ------ + ------ ------- +
| id | select_type |表|类型| possible_keys |关键| key_len | ref |行|额外|
+ ---- + ------------- + --------- + ------ + ---------- -------- + --------- + --------- + ------- + ------ + ------ ------- +
| 1 |简单|样品| ref | a_index,ab_index | a_index | 5 | const | 1 |使用where |
+ ---- + ------------- + --------- + ------ + ---------- -------- + --------- + --------- + ------- + ------ + ------ ------- +
答案 1 :(得分:0)
"快多少"在不了解数据内容的情况下,问题真的很难回答。如果您只为您的a
列编制索引,并且您有一个大表,但没有很多不同的a
值,那么MySQL仍然需要扫描您表的大部分内容。
仅a
或仅b
的索引可能(但不一定)比扫描整个表格更快。没有在真实数据上尝试它真的很难知道。这当然值得尝试。
专业提示:切勿使用SELECT *
,而是枚举所需列的名称。这是因为查询执行计划程序有时会在知道它不需要所有列时使用快捷方式。
您已经给出的查询,重写为
SELECT id,a,b
FROM samples
where a = '77345'
and b = '234234'
如果你有(a,b,id)的索引,那么确实非常快。这是因为MySQL可以满足索引的整个查询。它在索引中找到a,然后找到b。然后坐在那里是id值。这被称为复合覆盖指数。值得一读。