使用伪’loose index scan’优化max

  • 时间:
  • 浏览:0
  • 来源:5分11选5_5分3D

CREATE INDEX ix_log_machine_time ON log_table (log_machine, log_time);

+—-+————-+——-+——+—————+——+———+——+——+—–

| Machine 1 | 2010-05-07 23:59:13 |

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

| Machine 2 | 2010-05-07 23:58:42 |

| log_machine | max_log_time |

+—-+————-+———–+——-+———————+———————+—-

root@test 10:47:15>SELECT log_machine, MAX(log_time)

+—-+————-+——-+——+—————+——+———+——+——+—–

-> WHERE log_machine IN (‘Machine 1′,’Machine 2′,’Machine 3′,’Machine 4’);

-> WHERE log_machine IN (‘Machine 1′,’Machine 2′,’Machine 3′,’Machine 4’)

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

| Machine 4 | 2010-05-07 23:56:29 |

+—-+————-+——-+——+—————+——+———+——+——+——————————+

SELECT MAX(log_time)

-> group by log_machine

从执行计划中我们我们我们我们中,我们我们我们我们可不会可不能否就看端倪,优化器和底下一样不会可不能否直接找到满足条件的最大log_time,不过这次优化器前要首先在索引中定位到Machine 1,接着在

1 row in set (0.00 sec)

id INT NOT NULL PRIMARY KEY,

root@test 10:21:15>explain select max(log_time) from log_table;

log_time DATETIME NOT NULL

-> WHERE log_machine IN (‘Machine 1′,’Machine 2′,’Machine 3′,’Machine 4’)

1 row in set (0.00 sec)

FROM log_table

-> limit 1;

+—-+————-+———–+——-+———————+———————+—-

+————-+———————+

+—-+————-+———–+——-+———————+———————+—-

root@test 10:47:17>SELECT log_machine, MAX(log_time)

很多系列前缀值都为machine 1的记录中,在直接在定位到最后到第三根记录;

+————-+———————+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+————-+———————+

1 row in set (0.65 sec)

+—-+————-+——-+——+—————+——+———+——+——+—–

在mysql 5.5很久 ,mysql对loose index scan不会支持,这就是因为mysql的索引扫描通常前要另1个多 选泽的起点和终点,即使查询只前要其中很多不连续的行,

-> WHERE log_machine IN (‘Machine 1′,’Machine 2′,’Machine 3′,’Machine 4’)

+—-+————-+———–+——-+———————+———————+—-

root@test 10:16:18>explain SELECT MAX(log_time)

从执行计划中我们我们我们我们可不会可不能否清楚就看优化器使用到了using index for group by,另1个多 就可不会可不能否让优化器使用“伪松散索引扫描”,最终达到优化的目的;

| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |

-> FROM log_table

WHERE log_machine IN ($machines)

-> order by max_log_time desc

log_machine VARCHAR(20) NOT NULL,

执行时间从0.65s降到了0.00s,很多优化传输速率是非常明显的;

当然我们我们我们我们的索引时建立在log_time上的单列索引,很多很久 优化器发现不会扫描所有的叶子节点,而直接到最右叶子节点的尾部就可不会可不能否得到最大的log_time;

有很久 我们我们我们我们会遇到以下的应用场景:

+————-+———————+

mysql也会扫描起点和终点范围内的所有行;

| 1 | SIMPLE | log_table | range | ix_log_machine_time | ix_log_machine_time | 62 | NULL | 18 | Using where; Using index for group-by |

| Machine 1 | 2010-05-07 23:59:13 |

+—-+————-+———–+——-+———————+———————+—-

+————-+———————+

| Machine 1 | 2010-05-07 23:59:13 |

-> group by log_machine ;

| 1 | SIMPLE | log_table | range | ix_log_machine_time | ix_log_machine_time | 62 | NULL |5691500 | Using where; Using index |

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-> FROM log_table

如此 可能不支持loose index scan,现在我们我们我们我们传入的是另1个多 list,mysql不得不把所有满足在list中的machine的记录查询出来,因此 在哪此记录中得到最大的log_time;

+—-+————-+———–+——-+———————+———————+—-

+—-+————-+——-+——+—————+——+———+——+——+—–

-> FROM log_table

-> group by log_machine;

| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |

-> FROM log_table

-> FROM log_table

root@test 10:47:10>explain SELECT log_machine, MAX(log_time)

+————-+———————+

-> ;

-> FROM log_table

| Machine 3 | 2010-05-07 23:58:41 |

CREATE TABLE log_table (

root@test 10:52:21>explain SELECT log_machine, MAX(log_time) max_log_time

首先我们我们我们我们看看下面的查询:

我们我们我们我们建立的索引为:(log_machine,log_time),当我们我们我们我们传入单个machine的很久 ,传输速率加快传输速率,因此 当我们我们我们我们传入多个machines的很久 ,查询传输速率会一下子就降下来;

4 rows in set (0.00 sec)

| log_machine | MAX(log_time) |

-> WHERE log_machine IN (‘Machine 1’)

同理当我们我们我们我们在in list中传入单个值的很久 索引为 (log_machine, log_time):

+————-+———————+

| log_machine | MAX(log_time) |

很多很久 可能我们我们我们我们换三种生活想法,把每个machine的最大log_time计算出来,因此 在计算一次所有machine的中最大的log_time,另1个多 不仅可不会可不能否利用优化器不会可不能否直接得到每个machine的最大log_time的优化特点,因此 还可大大减少参与计算的行,另1个多 就可不会可不能否明显提升性能:

我们我们我们我们就看有5691500 行参加了运算;

-> WHERE log_machine IN (‘Machine 1′,’Machine 2′,’Machine 3′,’Machine 4’);

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

root@test 10:51:44>SELECT log_machine, MAX(log_time) max_log_time

+—-+————-+——-+——+—————+——+———+——+——+—–

+————-+———————+