复杂查询与分步查询

一个重要的查询设计课题是将复杂查询分解为多个简单查询是否会更好。在传统的数据库设计中强调尽可能地用更少的查询解决大量工作。在过往,这种方式会更好。这是因为以前的网络通讯成本更高以及考虑查询解析器和优化器的负荷。

然而,这种建议并不怎么适用于 MySQL,这是由于 MySQL 处理建立连接和断开连接的方式十分高效,并且对简单查询的响应很快。当今的网络速度相比以前也有了大幅度的提升。根据不同的服务端版本,MySQL 可以在普通机器上一秒内运行超过10万次的简单查询,并且在千兆网络上完成每秒2000次的查询通讯。因此,进行分布查询并不是过往说的那么糟糕。

相比于每秒遍历的数据行数,连接响应依旧是比较慢的。在内存数据中,这个时间达到了毫秒级。当然,使用尽可能的查询次数依旧是一个不错的选择。但是,有时我们可以通过拆分复杂查询为几个简单的查询来提高性能。接下来我们将展示一些示例。

在程序设计中,使用过多的查询是一个常犯的错误。例如,有些应用执行了10个单独的查询来获取10行数据(使用循环一条条获取),而这本可以通过一条查询10行数据的查询来完成。因此,这并不是倡导每次都做查询的拆分,而是根据实际情况来。

切分查询语句

另一个方式是拆分查询后重新再组合。通过在大数据量的查询拆分为更小范围的查询以减少每次影响的行数。

清洗旧数据就是一个典型的例子。周期性的清洗数据工作需要移除大量数据,进行这样的操作会长时间锁定大量数据行。这种操作还会产生事务日志、消耗大量资源并且会阻塞那些本不应该被打断的小数据量的查询。将DELETE语句切分后,使用中等规模的查询可以显著改善性能,并且在查询是重复的时候可以减少重复查询产生的额外延迟。例如下面的删除语句:

DELETE FROM messages WHERE created < DATE_SUB(NOW(), INTERVAL 3 MONTH);
rows_affected = 0do {  rows_affected = do_query (  "DELETE FROM messages WHERE created < DATE_SUB(NOW(), INTERVAL 3 MONTH)  LIMIT 10000")  } while rows_affected > 0

拆解联合查询

很多高性能的应用会拆解联合查询。可以通过将联合查询拆分为多个单表查询,然后在应用中再将结果组合起来。例如:

SELECT * FROM tagJOIN tag_post ON tag_post.tag_id=tag.id  JOIN post ON tag_post.post_id=post.idWHERE tag.tag='mysql';
SELECT * FROM tag WHERE tag='mysql';SELECT * FROM tag_post WHERE tag_id=1234;SELECT * FROM post WHERE post.id IN (123, 456, 567, 9098, 8904);
  • 缓存机制会更有效。很多应用直接使用 ORM 映射数据表。在这个例子中,如果 tag 为 mysql 的对象已经被缓存了,第一条查询就会跳过。如果 posts 中 id 为123,567或9908在缓存中,则可以从 IN 列表中移除这几个。通过这种策略,查询缓存会得到相应的受益。如果只有其中的一个表经常变化,拆解联合查询可以减少缓存失效的次数。
  • 单独执行这些查询有时候可以减少锁表的机会。
  • 通过这种方式很容易扩展数据库,并把数据表放到不同的机器上。
  • 查询自身可以进行优化。这个例子中,使用 IN 查询替代联合查询后,MySQL 对行 ID 进行排序和获取数据行有可能会更优。
  • 可以减少冗余的行访问。使用这种方式意味着只做一次数据行获取,而在联合查询中有可能重复获取相同的数据。基于这种原因,这种拆解方式也可能会减少整个网络负荷和内存占用。
  • 扩展一下,也可以通过人为进行哈希联合查询来替代MySQL联合查询的嵌套循环,哈希联合查询也可能会更有效。

最终可以看到,通过拆解联合查询可以使得缓存复用性更高,多服务器分布式数据方案更简单,并可以在大的数据表中使用 IN 查询替代联合查询或同一张表的多次重复查询。

更多相关文章

  1. 【安卓笔记】android客户端与服务端交互的三种方式
  2. Android(Java):滑动删除实现——重写onTouch
  3. Android学习--Android带删除按钮的ListView
  4. android显示gif图片
  5. Android三种实现定时器的方法
  6. android 沉浸式状态栏的三种方法
  7. Android(安卓)自绘输入框
  8. android 竖屏activity跳转横屏activity返回时数据消失
  9. fullScreen时的软键盘监听(非重写Layout方式)

随机推荐

  1. 在CMD查看Mysql数据时出现中文乱码
  2. 一个mysql数据库的问题啊,我都摸索两天了
  3. 用delphi5修改sql server2000出现“键列
  4. MySQL存储引擎中的MyISAM和InnoDB
  5. 在C#中运用 SQLite
  6. 关与批处理的问题 一个批处理调用SQLplus
  7. spring-boot mybatis mapper生成sql有问
  8. UPDATE Sql不能在集合中聚合
  9. MySQL入门很简单: 2 MySQL数据类型
  10. 在线求助.Select语句包含ERP单据内表头与