使用伪’loose index scan’优化max

  • 时间:
  • 浏览:0

从执行计划中亲戚亲戚朋友中,亲戚亲戚朋友还必须看后端倪,优化器和上端一样都都可不都可不可以直接找到满足条件的最大log_time,不过这次优化器必须首先在索引中定位到Machine 1,接着在

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

WHERE log_machine IN ($machines)

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

-> FROM log_table

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

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

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

4 rows in set (0.00 sec)

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

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

-> ;

同理当亲戚亲戚朋友在in list中传入单个值的前一天索引为 (log_machine, log_time):

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

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

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

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

从执行计划中亲戚亲戚朋友还必须清楚看后优化器使用到了using index for group by,原来就还必须让优化器使用“伪松散索引扫描”,最终达到优化的目的;

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

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

首先亲戚亲戚朋友看看下面的查询:

在mysql 5.5前一天,mysql对loose index scan并不支持,这就原应着分析mysql的索引扫描通常必须原来选者的起点和终点,即使查询只必须其中一些不连续的行,

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

亲戚亲戚朋友看后有5691100 行参加了运算;

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

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

1 row in set (0.00 sec)

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

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

SELECT MAX(log_time)

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

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

那末 可能性不支持loose index scan,现在亲戚亲戚朋友传入的是原来list,mysql不得不把所有满足在list中的machine的记录查询出来,日后 在那先 记录中得到最大的log_time;

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

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

1 row in set (0.65 sec)

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

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

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

-> FROM log_table

| log_machine | MAX(log_time) |

-> FROM log_table

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

-> group by log_machine;

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

有前一天亲戚亲戚朋友会遇到以下的应用场景:

亲戚亲戚朋友建立的索引为:(log_machine,log_time),当亲戚亲戚朋友传入单个machine的前一天,波特率更快,日后 当亲戚亲戚朋友传入多个machines的前一天,查询波特率会一下子就降下来;

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

CREATE TABLE log_table (

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

| log_machine | max_log_time |

-> FROM log_table

-> group by log_machine

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

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

log_time DATETIME NOT NULL

1 row in set (0.00 sec)

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

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

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

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

| log_machine | MAX(log_time) |

CREATE INDEX ix_log_machine_time ON log_table (log_machine, log_time);

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

| 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 |

id INT NOT NULL PRIMARY KEY,

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

一些前一天可能性亲戚亲戚朋友换一些想法,把每个machine的最大log_time计算出来,日后 在计算一次所有machine的中最大的log_time,原来不仅还必须利用优化器都都可不都可不可以直接得到每个machine的最大log_time的优化特点,日后 还可大大减少参与计算的行,原来就还必须明显提升性能:

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

-> WHERE log_machine IN (‘Machine 1’)

log_machine VARCHAR(20) NOT NULL,

FROM log_table

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

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

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

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

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

执行时间从0.65s降到了0.00s,一些优化波特率是非常明显的;

-> FROM log_table

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

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

-> group by log_machine ;

-> limit 1;

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

-> order by max_log_time desc

当然亲戚亲戚朋友的索引时建立在log_time上的单列索引,一些前一天优化器发现不想扫描所有的叶子节点,而直接到最右叶子节点的尾部就还必须得到最大的log_time;

-> FROM log_table

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