某同学写了以下的查询sql,通过每次对limit的offset进行增大,取到不同批数据做处理,比如,第一次是limit 0,100,第二次是limit100,100,现在该同学发现,随着offset的增大,sql变得越来越慢,这个时候让你进行优化,你会怎么做呢?
1 | create table 'account'{ |
1 | select * from account limit ?,? |
优化方案:
id >= 的形式
1
select * from account where id >= (select id from account limit 80000,1) limit 100
利用join
1
select * from account a join(select id from account limit 80000,100) b on a.id = b.id;
InnoDB存储引擎支持覆盖索引,即从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。使用覆盖索引的一个好处是辅助索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作。
对于InnoDB存储引擎的辅助索引而言,由于其包含了主键信息,因此其叶子结点存放的数据为(primary key1, primary key2, …, key1, key2, …)。
例如,下列语句都可仅使用一次辅助联合索引来完成查询:
1 | select key2 from table where key1=xxx; |
覆盖索引的另一个好处是对某些统计问题而言的。
1 | select count(*) from buy_log; |
InnoDB存储引擎并不会选择通过查询聚集索引来进行统计。由于bug_log表上还有辅助索引,而辅助索引远小于聚集索引,选择辅助索引可以减少IO操作,故优化器的选择为userid索引。
聚集索引(clustered index)就是按照每张表的主键构造一棵B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。同B+树数据结构一样, 每个数据页都通过一个双向链表来进行链接。
辅助索引(Secondary Index,也称非聚集索引),叶子节点并不包含行记录的全部数据。叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含了一个书签(bookmark)。该书签用来告诉InnoDB存储引擎哪里可以找到与索引相对应的行数据。由于InnoDB存储引擎表是索引组织表,因此InnoDB存储引擎的辅助索引的书签就是相应
行数据的聚集索引键。图5-15显示了InnoDB存储引擎中辅助索引与聚集索引的关系。.