优化查询不能只看慢查询日志,常规来说,0.01 秒以上的查询,都是不
够优化的。
实战范例
和上案例类似,某游戏社区要显示用户动态,select * from userfeed where
uid=$uid order by lastlogin desc limit 0,30; 初期默认以 uid 为索引字段,
查询为命中所有 uid=$uid 的结果按照 lastlogin 排序。 当用户行为非常频
繁时,该 SQL 索引命中影响结果集有数百乃至数千条记录。查询效率超
过 0.01 秒,并发较大时数据库压力较大。
解决方案:将索引改为 uid+lastlogin 复合索引,索引直接命中影响结果
集 30 条,查询效率提高了 10 倍,平均在 0.001 秒,数据库压力骤降。
影响结果集的常见误区
影响结果集并不是说数据查询出来的结果数或操作影响的结果数,而是查询
条件的索引所命中的结果数。
实战范例
某游戏数据库使用了 innodb,innodb 是行级锁,理论上很少存在锁表情
况。出现了一个 SQL 语句(delete from tabname where xid=…),这个 SQL
非常用 SQL,仅在特定情况下出现,每天出现频繁度不高(一天仅 10 次
左右),数据表容量百万级,但是这个 xid 未建立索引,于是悲惨的事
情发生了,当执行这条 delete 的时候,真正删除的记录非常少,也许一
到两条,也许一条都没有;但是!由于这个 xid 未建立索引,delete 操作
时遍历全表记录,全表被 delete 操作锁定,select 操作全部被 locked,由
于百万条记录遍历时间较长,期间大量 select 被阻塞,数据库连接过多
崩溃。
这种非高发请求,操作目标很少的 SQL,因未使用索引,连带导致整个
数据库的查询阻塞,需要极大提高警觉。
总结:
影响结果集是搜索条件索引命中的结果集,而非输出和操作的结果集。
影响结果集越趋近于实际输出或操作的目标结果集,索引效率越高。
请注意,我这里永远不会讲关于外键和 join 的优化,因为在我们的体系里,
这是根本不允许的! 架构优化部分会解释为什么。
理解执行状态
常见分析手段
慢查询日志,关注重点如下
是否锁定,及锁定时间
如存在锁定,则该慢查询通常是因锁定因素导致,本身无需优化,需解
决锁定问题。
影响结果集