常见性能问题选编(转载) - zLulus/My_Note GitHub Wiki

分页

两个典型场景:
1、 评论(任何简单的列表)
2、 电商(带复杂筛选功能的列表)

评论

特点:不支持查询条件,只需要分页
非常常见的场景

查询一篇文章的评论

MYSQL语法

select article_id, article_name, article_content 
from message
where article_id=3
order by id desc limit 0,20  
--(0=>10000呢?) 

MSSQL语法参考OFFSET/FETCH NEXT

问题:扫描行数太多

扫描行数:page_size*page_index
随着翻页数的上升,性能下降极大
一个爬虫就不小心搞死你

利用索引减少扫描

select article_id, article_name, article_content 
from message
where article_id=3 & id<$last_message_id
order by id desc 
limit $ page_size

…?article=3&page=3&last_id=1502934

粗看时间复杂度
O(page_sizepage_indexlog(total_rows))=>O(page_size *log(total_rows))
log(total_rows)用于近似表示BTree的索引效率
没有带上索引情况非常糟糕

适用场景
1、 无法快速生成完整分页链接,适合只需要上一页、下一页的场景
2、 对于大部分的瀑布流场景很好用

更高的效率?
放弃数据库,采用专用的数据结构(eg.Redis)
List O(1) | Sorted Sets O(log(n))

场景2:电商

特点:查询复杂,大量条件随机排列组合

用数据库的困难

不同类目的数据字段不一样,不分表的话只能用NoSql?
就算字段固定,索引也无法设计
全文索引、同义词 怎么办?

基于搜索引擎的方案

打造以ES为核心的系统

计数器

统计数量
通用计数器、专用计数器
Bitmap
微博计数器的设计
http://blog.cydu.net/weidesign/2012/09/09/weibo-counter-service-design-2/
http://velocity.oreilly.com.cn/2012/ppts/duchuanying.pdf
统计UV? try HyperLogLogs
https://redis.io/topics/data-types-intro#hyperloglogs