zoukankan      html  css  js  c++  java
  • 生产力的重大瓶颈 SQL+关系型数据库

    最近我发现在上次Release中,由于时间太紧,个人水平有限,在许多存储过程中用了这么一个子查询,用以过滤用户没有权限访问的交易业务,类似这种形式:

    DECLARE @IDs TABLE(GroupID INT)
    --填充该用户无权限的组ID
    SELECT * FROM Deals WHERE GroupID NOT IN (SELECT GroupID FROM @IDs) 
    

     当时加上这个子查询时,因为前面还有很多连接操作,认为慢也正常。但是当我要将这段逻辑扩展到其他功能上时,我犹豫了,有些很常用的查询也要等个近一分钟,就算用户能忍受,我自己都接受不了,于是我试着把(SELECT GroupID FROM @IDs)换成(3,4,5,...)这种直接数字。结果一试,大吃一惊,原来时间几十秒的执行,一秒内跑完!

    自己太天真了,原来SQL Server根本不会去优化子查询,将结果缓存下来并内联。

    不想用动态SQL,于是google一下,找到子查询(in not )转化为连接查询的方法,上面语句转化为:

    SELECT * FROM Deals d
    LEFT JOIN @IDs i ON i.GroupID = d.GroupID 
    WHERE i.GroupID IS NULL
    

    也基本是一秒内完成。

    了解这个后,心情又沉重又悲痛。悲痛的是我工作了这么多年,SQL还是菜鸟,而且同事中没有一个能指出来这么简单的问题。沉重的是从SQL Server 2000到2012,还是老样子,除了不能优化子查询,还是定义集合变量,依然笨拙的聚合操作,可怜的SQL复用性支持,难于调试。其实,不只是SQL Server,这是所有关系型数据库,积重难返的通病,是已经严重滞后的SQL语言对生产力的巨大桎梏。

    在我经历以数据驱动的系统,可能SQL开发代码量只占一小部分,但其工作量要数倍于面向对象语言,而且Bug的集中营,还集中了几乎全部系统性能的勒索。SQL不但谋杀程序员的青春,更绑架了无数程序员的思想,不会学习新技术,不会复用代码,不会单元测试,就是被SQL绑架的程序员。

    在一个崭新的系统你们不会觉得,这时数据库像一个温顺可爱的小猫,但随着它一天天长大,数据一天天增加,你会发现它变成了一头可怕的老虎,不是只有程序员,还有用户,部署人员,DBA,都要小心翼翼的伺候着。

    看着被吃掉的时间和金钱,我们不能再养虎为患了。那么我们现在应该怎么做呢?

    小型服务器系统和中小型客户端系统,比如手机上的一个应用,仍然可以用关系型数据库,但一定要把它放在ORM的笼子里,而且要提防它长大。

    区别是否该用RDBMS,有一个直观标准可以作参考,就是用Visual Studio或SharpDevelop中的Entity Model设计器,如果对象排满了一页,关系七零八落看不清楚,就该考虑No-SQL数据库。

    对于大型客户端系统,应该用强对象型数据库,比如db4o。对于中大型服务器系统,应该采用分布式对象数据库,比如MongoDB。

    或者,根据系统性能需要,开发专门的存储格式。

    对于巨型服务器系统,比如Google/Facebook,除了Hadoop这类分布文件系统,没有第二选择。

    那种几百个表,几千个存储过程的系统,是时候进入历史的垃圾堆了。我还算庆幸,手头这个项目再用一年左右就会淘汰了,如果你的现在的工作或新工作也是这种项目,请好好考虑一下自己的职业发展吧。

  • 相关阅读:
    乔治·奥威尔的六条有效写作的规则
    读书:《个人形成论》 Carl R. Rogers
    想想体制性的生存法则
    每一个山峰都建立在同一座山上
    读书笔记:这些道理没有人告诉过你(二)
    举国的不仅仅是运动员
    参加了一个社会化营销策划比赛整理一下参考资料
    读书:《个人形成论》2 Carl R. Rogers
    前端避坑指南丨辛辛苦苦开发的 APP 竟然被判定为简单网页打包?
    Entify Framework 4.1[问题集] 一个实体的双向依赖引起的错误
  • 原文地址:https://www.cnblogs.com/XmNotes/p/2976199.html
Copyright © 2011-2022 走看看