3.前缀索引和后缀索引
前缀索引听得比较多,优点是减少索引的长度,缺点是排序不能使用前缀索引(影响distinct/order/group),也不会出现Covering Index(只读取索引就能满足查询)。
后缀索引还是首次听到,孤陋寡闻了。因为MySQL不支持反向索引,所有有时候查询会有问题,例如字段blog保存用户的博客地址 (http://willko.javaeye.com),那需要查询某个域名有多少个用户就不好查询,可以用一个额外的字段反转保存。 blog_reverse:moc.eyeavaj.willko://ptth,这样就很容易查到javaeye.com(moc.eyeavaj)有 多少用户了,并可以使用索引,也就是解决了 LIKE '%?'的问题,因为查询反转成LIKE '?%'了。
4.散列数据
散列数据就是把原本只有一条记录的散列成多条,充分利用InnoDB行锁的特性,提高并发。
例如,之前是UPDATE hit_counter SET cnt = cnt + 1 WHERE id = ?
散列后是 UPDATE hit_counter SET cnt = cnt + 1 WHERE id = ? AND slot = rand() * 100
散列后查询需要合并数据。
笔记与心得:innodb是行锁。所以啊它在处理这种大的并发的时候是非常高效的。哦因为是行锁并发性能要高。所以在大的论坛的时候是用innodb哦!
5.优化limit和offset
MySQL的limit工作原理就是先读取n条记录,然后抛弃前n条,读m条想要的,所以n越大,性能会越差。
优化前SQL: SELECT * FROM member ORDER BY last_active LIMIT 50,5
优化后SQL: SELECT * FROM member INNER JOIN (SELECT member_id FROM member ORDER BY last_active LIMIT 50, 5) USING (member_id)
分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。
笔记:这个我得要好好借鉴一下了。因为现在的表如果有超过近千万条记录的话。
SELECT * FROM member ORDER BY last_active LIMIT 50,5
SELECT * FROM member INNER JOIN (SELECT member_id FROM member ORDER BY last_active LIMIT 50, 5) USING (member_id)
子查询虽然被人骂但用得好还是比较爽的。这里面我们就使用了子查询来提高查询性能
<!--[if !supportLists]-->1、 <!--[endif]-->读索引SELECT member_id FROM member ORDER BY last_active LIMIT 50, 5