MSSQL的弱智设计之处!

iamybj 2010-12-20 11:54:14
哥最近使用MSSQL,用出火来了,不仅仅是因为不熟悉,而且是因为MSSQL那些自以为是、闭门造车、落后过时的设计!
所以要开此贴,把这些弱智之处记录下来!

1、select * from tablexxx; 这样没有order by 的sql 默认按照主码排序问题。
首先我没有让你排序,你给我排序干嘛?你不知道排序数据会造成效率严重下降吗?
就算你是按照聚簇索引输出的而不是索引排序,我让你建聚簇索引了吗?你不知道聚簇索引在插入和更新数据时会有效率问题吗?

2、数据字典中大量使用数字而不是易读的字符串代表名称、类型等问题。
这就是为什么google上很多syscolumns表中各个列代表什么意思的文章出现的原因。难道用对象名、数据类型名等等这些字符串不行吗?你以为用数字ID就比字符串效率低了?

3、一次性返回所有行的问题。
只要数据量稍微多点,sqlserver都会很慢,为什么?因为它会把所有数据都一次性查出来?有必要吗?你不知道首先快速的返还出100行来,等我请求第101行的时候你再返回200行吗?

4、 Convert等这样又像函数又像语句的不知道叫啥好的东西的问题。
你要是定义成Convert(‘varchar’, column1..)这样我还可以理解,但是你竟然定义成Convert(varchar, column1..),那我问你varchar是什么啊? 是字符串,那Convert就是一个函数,应该加上单引号, 如果是类型,那Convert就应该是语句,格式就应该是Convert varchar from column1等等这样的格式,而不是类似一个函数。。。

5、未完待续。。。
...全文
413 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
feilniu 2010-12-27
  • 打赏
  • 举报
回复
咱也改围观。看LZ在自以为是的大道上绝尘而去。
sky_too_sky 2010-12-22
  • 打赏
  • 举报
回复
这个问题取舍与满足多数人群,像楼主这样的愤青毕竟是少数。。。
Stephanie_Lee 2010-12-21
  • 打赏
  • 举报
回复
任何人的学习过程中或多或少都有过自满和狂妄的阶段。但愿LZ能走过这个阶段。
此话说的严重在理~!
feilniu 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 guguda2008 的回复:]

如果这么说我觉得就没法沟通了,feilniu大大继续跟他扯吧,我撤退。
[/Quote]

任何人的学习过程中或多或少都有过自满和狂妄的阶段。但愿LZ能走过这个阶段。

我也尽力了。闪人~~
feilniu 2010-12-21
  • 打赏
  • 举报
回复
MSSQL默认按照主码输出只可能有两个原因:
(这一步推理不严格。全表数据按主码顺序输出,并不能说明主码是聚集索引,也可能是非聚集覆盖索引。不过这点疏漏无碍。大体逻辑正确。)
1、默认在主码上建立了聚簇索引,造成整个表成了“索引排序表”,这种表在插入和更新数据时,行中的非主码数据也会按照聚簇索引的顺序存放在表的文件里,从而造成效率下降。
(MSSQL的主码的确是默认为聚集索引。聚集索引优在查询快捷,劣在更新消耗。这个要综合考量。数据按聚集索引顺序存储,可MSSQL并不是简单地把所有数据线性地摆放在磁盘里。事实证明MSSQL把主码默认为聚集索引的设计并不是什么错误的决定。)
2、MSSQL的执行计划走了主码索引,从而是数据输出按照主码排序。但是我们都知道,走索引并不一定是效率最高的,很多时候还不如全表扫面速度快,(很多时候并不是总是,也不能说明就是这个时候)这说明,MSSQL的优化器设计过时和不够智能的。(所以最后的结论是武断和不负责任的)
3、不可能有任何第三种可能,(基本正确)但是上面两种情况都证明MSSQL的设计过时。(结论武断)
feilniu 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 iamybj 的回复:]

alter session set optimizer_mode='FIRST_ROWS_1000' 怎么解释?
[/Quote]

--SQL Server
SET ROWCOUNT 1000
guguda2008 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 iamybj 的回复:]

引用 14 楼 sz_haitao 的回复:

这些倒不是大问题,最大的问题是:select出来结果的时候,没有自动加一个序号列foid
如果有了它,分页就是很简单的事情了:
select * from (
select * from tb where ... order by ...
) a where foid>10000 and foid<10020
或者
select t……
[/Quote]
如果这么说我觉得就没法沟通了,feilniu大大继续跟他扯吧,我撤退。
feilniu 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 iamybj 的回复:]

聚簇索引肯定就是和oracle里的索引排序表一样,指的是表里的数据也是按照索引的顺序存储的,否则就不会有一个表只有一个聚簇索引的限制了。这也说明,mssql对"聚簇索引"的命名方法不对,还是“索引排序表”更准确。
[/Quote]

Index Organized Tables(索引排序表)是Oracle一家的叫法;Clustered Index(聚集索引,或译聚簇索引)是数据库领域通行的叫法,当然也是MSSQL采用的叫法。

采用什么叫法主要要看交流对象,入乡随俗。在Oracle区自然叫索引排序表,在MSSQL区自然叫聚集索引,在数据库理论领域进行探讨也叫聚集索引。

LZ敢于轻易说出“这也说明,mssql对"聚簇索引"的命名方法不对”,真是无知者无畏。(这里的“无知”只是对知识的描述,不是对人格的侮辱)

在世界面前,人类都是无知的。关键是要知道自己知道什么以及自己不知道什么,然后保持虚怀若谷的态度。无知+自大是最可怕的。
wing7742 2010-12-21
  • 打赏
  • 举报
回复
萝卜青菜各有所爱
iamybj 2010-12-20
  • 打赏
  • 举报
回复
1、楼上的哥们,我先插入了一个ID为10的行,然后又插入了一个ID为1的行,结果我不用order by 直接查询时,它竟然返回ID为1的行在id为10的行前面,怎么解释?不管是自动按照主码排序,还是自动按照主码存放了数据,都会造成严重的性能的降低,都是自作多情和多此一举。难道让ID为1的在id为10的后面输出不行吗?

2、你说把ID和Name分开,那ID难道就一定得是数字吗?

2、你说一次性不返回所有行是bug,我说不返回所有的行吗?我说不必一次性返回,而是应该分批返回。好比让你吃饭,你一次把一辈子的饭都吃了,肯定会撑死,但是饿的时候吃一顿,慢慢的把所有的饭都吃了才是最合适的。

4、你说是枚举类型,那我问你建表是后面的那个类型可以是枚举类型和常量吗?就算是枚举类型,那也应该换一个别的样子,而不是和建表时的类型一样。
zhou247791572 2010-12-20
  • 打赏
  • 举报
回复
。。。。。。。。楼主有见解
feilniu 2010-12-20
  • 打赏
  • 举报
回复
1、select * from tablexxx; 这样没有order by 的sql 默认按照主码排序问题。
首先我没有让你排序,你给我排序干嘛?你不知道排序数据会造成效率严重下降吗?
就算你是按照聚簇索引输出的而不是索引排序,我让你建聚簇索引了吗?你不知道聚簇索引在插入和更新数据时会有效率问题吗?
====
不指定ORDER BY,查询结果会按照数据的物理顺序返回,即以最直接方便的顺序返回。不会额外排序。
表上如果有聚集索引,那一定是你让它建的。别赖别人。
SQL Server开发团队在这点上比LZ想象得要聪明得多。

2、数据字典中大量使用数字而不是易读的字符串代表名称、类型等问题。
这就是为什么google上很多syscolumns表中各个列代表什么意思的文章出现的原因。难道用对象名、数据类型名等等这些字符串不行吗?你以为用数字ID就比字符串效率低了?
====
表示元数据的系统视图太符合范式了,把类型的ID和类型的Name分开了。
确实应该再加一层更Human-readable的视图。

3、一次性返回所有行的问题。
只要数据量稍微多点,sqlserver都会很慢,为什么?因为它会把所有数据都一次性查出来?有必要吗?你不知道首先快速的返还出100行来,等我请求第101行的时候你再返回200行吗?
====
SELECT * FROM table,就是要查询所有记录,如果只返回一部分,那是bug。
很多工具都假定程序员是聪明的,知道自己要做什么。比如Linux的命令行都是直接返回执行结果,而不像Windows的CMD命令,常常自以为是地自动分页。
不过既然在SSMS中查询数据,通常只是为了查看示例而不是所有数据,那SSMS在这一点上的确应该遵守微软的传统,加一个提醒:“数据量很大,可能比较慢”,等等之类。但众口难调,这样的设计也一定会被骂。

4、 Convert等这样又像函数又像语句的不知道叫啥好的东西的问题。
你要是定义成Convert(‘varchar’, column1..)这样我还可以理解,但是你竟然定义成Convert(varchar, column1..),那我问你varchar是什么啊? 是字符串,那Convert就是一个函数,应该加上单引号, 如果是类型,那Convert就应该是语句,格式就应该是Convert varchar from column1等等这样的格式,而不是类似一个函数。。。
====
LZ没听说过枚举类型和常量吗?
类型转换的SQL标准写法:CAST(column AS varchar),CONVERT是SQL Server加的,用来处理不同style的转换问题。
LZ愿意的话,可以设计个更好用的语法格式。
王向飞 2010-12-20
  • 打赏
  • 举报
回复
此贴要火,前排观望。
feilniu 2010-12-20
  • 打赏
  • 举报
回复
跟上次那个“侮辱智商”的帖子异曲同工啊:
http://topic.csdn.net/u/20101212/07/cfd81a8f-b6e6-4af2-b107-654cd29f955d.html
百年树人 2010-12-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 haiwer 的回复:]
我围观
[/Quote]
+1
a785126172 2010-12-20
  • 打赏
  • 举报
回复
呵呵 哥们比较愤青 啊··
q461714878 2010-12-20
  • 打赏
  • 举报
回复
微软的方向是大众化的,不是专业化的。在追求易用性上必然会损失性能。这是微软的成功之道!!牛人分析的,不是我啊!想想windows 和 dos 就知道了。
Tirecoed 2010-12-20
  • 打赏
  • 举报
回复
先不说技术。
楼主可以试着做这件事情:两臂膀张开,然后以较快的速度把左右手的手指叉起来;再做一次;再做一次;如果有兴趣的话,再多几次,




做了吗?
你会发现你每次做的时候,都是某一只手的大拇指压着另一只手。
那现在再几次,要求以前被压着的大拇指压着以前压着的大拇指。
感觉怎样,不太习惯吧?
再多做几次,
有点习惯了吧?

其实都是不太习惯造成了你的愤怒。
我也不太习惯SQL Server里某些东西,比如有了char,又有nchar,像mysql那样指定内码不多好?
后来发现Informix也有char与nchar,我相信总是有原因的。

凡事,习惯了就好了!
iamybj 2010-12-20
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 feilniu 的回复:]

引用 18 楼 guguda2008 的回复:

我知道LZ一定会说“凭什么我不说他就给我建个聚集索引,应该是我让他建他才能建的,不知道聚簇索引在插入和更新数据时会有效率问题吗?”


所以LZ肯定是不知道非聚集索引在插入和更新时也会有效率问题。

如果LZ知道一种不使用现有B+树索引的机制来实现主键的功能,那真是跨时代的发现啊。
[/Quote]

一行数据包括主码和非主码,主码当然可以按照排序存储,而且因为主码大都是小数据块,所以效率可以忍受,但是其他的非主码数据呢,难道也要排序存储?

MSSQL默认按照主码输出只可能有两个原因:
1、默认在主码上建立了聚簇索引,造成整个表成了“索引排序表”,这种表在插入和更新数据时,行中的非主码数据也会按照聚簇索引的顺序存放在表的文件里,从而造成效率下降。
2、MSSQL的执行计划走了主码索引,从而是数据输出按照主码排序。但是我们都知道,走索引并不一定是效率最高的,很多时候还不如全表扫面速度快,这说明,MSSQL的优化器设计过时和不够智能的。
3、不可能有任何第三种可能,但是上面两种情况都证明MSSQL的设计过时。

当然,还是微软自己说得对,微软仅仅是一家为中小企业提供服务的公司。
iamybj 2010-12-20
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 xxyj6450 的回复:]

oracle没有分批返回数据吧?楼主是不是把pl/sql工具和oracle混为一谈了?那个分页是那工具分页的,不是oracle本身分的吧?其实sql2005的sql server management studio也有类似的功能,它会在你拉动滚动条的时候逐步加载数据.但这不是数据库本身的功能吧.

另外,当你用异步方式提取数据时,数据是可以一批一批返回的.
[/Quote]

alter session set optimizer_mode='FIRST_ROWS_1000' 怎么解释?
加载更多回复(23)

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧