接着上面的问题 都是优化问题,唉 都不知道要怎么学

HelloChina 发布于 2012/07/01 19:02
阅读 289
收藏 1

直接问不太好,我也不知道要怎么优化,大家帮忙看下 要怎么看这种问题

 

CREATE TABLE topid{

topicId int not null primary key auto_increment,
title text,
author varchar(30),
content blob,
isDeleted int
......   //好像在author上定义了一个索引
}
CREATE TABLE reply{
topicId int foreign key,
replyId int primary key auto_increment,
replyAuthor varchar(30),
replyTime datetime,
context blob
....... //定义了一个索引和key
}
一个为主题表,一个为回复表。

1.问从性能上考虑,这样做有什么不足。
2.查询回复时间不超过一个特定的时间段,回复的作者名字以MIKE开头的主题
   的title,以如下的查询:
   select * from topic where replyid in (select replyid from reply where replyAuthor like 'mike%' and (currentTime()-replyTime   从性能上考虑上述的查询语句有什么不足?
   如何进行优化?
加载中
0
王昊然
王昊然

1.这样的表设计的话感觉冗余很多,完全可以设计在一张表里,通过一个字段关联,这样的话查询的时候只在这一个表上操作,性能自然比这个高

2.和1一样,我觉得这个表设计的就有问题,所以导致SQL查询的效率不高,如果非要2个表的话,那至少关联字段应该有

 

感觉出这题的人水平也好不到哪去。。。

王昊然
王昊然
回复 @xyz555 : 恩,主题表独立出来,回复表按需求设计,学习了,谢谢!
xyz555
xyz555
回复 @王昊然 : 如果是无限的按回复回复.....这样是需要无级分类,不过这种方式是要牺牲速度的,如果按性能的话还是按OSC这样不是很好,呵呵。况且如果说按主题搜索频率高的话,主题还是可以独立出来,回复可以无级分类。
王昊然
王昊然
回复 @xyz555 : OSC三个表的确能解决问题,如果像Discuz样的论坛,回复要占一个楼层,是否需要无级分类呢
xyz555
xyz555
像这个论坛,其实只有3层。只要设计:主题、回复、回复的回复3个表,就可以很好的消除递归。
xyz555
xyz555
回复 @王昊然 : 消除递归是提升速度的一个方法。
下一页
0
宏哥
宏哥

引用来自“王昊然”的答案

1.这样的表设计的话感觉冗余很多,完全可以设计在一张表里,通过一个字段关联,这样的话查询的时候只在这一个表上操作,性能自然比这个高

2.和1一样,我觉得这个表设计的就有问题,所以导致SQL查询的效率不高,如果非要2个表的话,那至少关联字段应该有

 

感觉出这题的人水平也好不到哪去。。。

mysql 只能冗余, 它没有关系计算能力. 所有的mysql系统都在这种表设计模式.所以搞mysql的都要写程序维护数据一致性,加班到死.

对楼主:

一般来说, 一个毕业生从0开始学习数据库, 3-6个月就能达到不错的水平了.并不是什么难事.

但是

如果是熟悉mysql,并且只熟悉mysql的, 这个过程至少需要 5-10年. Mysql 是让你脑残的东西.

宏哥
宏哥
回复 @HelloChina : 恶性循环, 越穷越忙,越忙越穷. 越没有时间,就越要挤出时间,否则咋办.
HelloChina
HelloChina
唉,大学白过了,现在没有时间,越看 越多东西不会
0
szf
szf

引用来自“宏哥”的答案

引用来自“王昊然”的答案

1.这样的表设计的话感觉冗余很多,完全可以设计在一张表里,通过一个字段关联,这样的话查询的时候只在这一个表上操作,性能自然比这个高

2.和1一样,我觉得这个表设计的就有问题,所以导致SQL查询的效率不高,如果非要2个表的话,那至少关联字段应该有

 

感觉出这题的人水平也好不到哪去。。。

mysql 只能冗余, 它没有关系计算能力. 所有的mysql系统都在这种表设计模式.所以搞mysql的都要写程序维护数据一致性,加班到死.

对楼主:

一般来说, 一个毕业生从0开始学习数据库, 3-6个月就能达到不错的水平了.并不是什么难事.

但是

如果是熟悉mysql,并且只熟悉mysql的, 这个过程至少需要 5-10年. Mysql 是让你脑残的东西.

在对待MySQL的态度上,我挺佩服宏哥表现出来的一贯和执着的,但貌似这次宏哥可能没空看题吧,我就帮宏哥补充一下:

使用where xxx in (select ...)的子查询SQL,在oracle上的确是效率比其它数据库都高(sql2000/2005/2008,mysql 5.0/5.1, sybase 10/11/12,oracle 8i/9i/10g/11g我都用过),可能是跟它有UNDOTBS这个设计有关(我猜的,一直都无法精通oracle, 另题外:oracle的复杂结构是有道理的,专用的多进程也是很有用的)

但类似

select * from topic where replyid in (select replyid from reply where replyAuthor like 'mike%' and (currentTime()-replyTime 

这种写法,更通常是写成left join方式:

select * from topic a

left join reply b on a.topicid=b.topicid where replyAuthor like 'mike%' and replyTime<(currentTime()-?)



这里的优化上要注意的是:

1.不能用(currentTime()-replyTime) > ? 的方式去比较时间,会造成计算字段无法使用索引的问题(任何关系数据库都是一样道理,包括最猛的oracle)

2.对replyAuthor 和 replyTime使用联合索引,这样可以在此查询中被优化器用上(但哪个在前哪个在后也有学问,自己深入后再研究吧)

至于设计,我个人觉得问题不大,这个设计已经很合理了。虽然关系数据库中有增加表设计冗余度来提高性能的做法,但以我的项目经验来说,先不说这种做法不能带来多少性能上巨大的提升,就说设计烂了要修正比数据库性能低下要优化来说难得多。

至于 mysql是不是支持事务,这个要视乎它使用哪个存储引擎而定,innodb, ndb都是支持事务的,可以由数据库层面确保满足事务一致性,而不需要应用程序额外的代码,在学习的态度上,兼听则明!
0
宏哥
宏哥

引用来自“szf”的答案

引用来自“宏哥”的答案

引用来自“王昊然”的答案

1.这样的表设计的话感觉冗余很多,完全可以设计在一张表里,通过一个字段关联,这样的话查询的时候只在这一个表上操作,性能自然比这个高

2.和1一样,我觉得这个表设计的就有问题,所以导致SQL查询的效率不高,如果非要2个表的话,那至少关联字段应该有

 

感觉出这题的人水平也好不到哪去。。。

mysql 只能冗余, 它没有关系计算能力. 所有的mysql系统都在这种表设计模式.所以搞mysql的都要写程序维护数据一致性,加班到死.

对楼主:

一般来说, 一个毕业生从0开始学习数据库, 3-6个月就能达到不错的水平了.并不是什么难事.

但是

如果是熟悉mysql,并且只熟悉mysql的, 这个过程至少需要 5-10年. Mysql 是让你脑残的东西.

在对待MySQL的态度上,我挺佩服宏哥表现出来的一贯和执着的,但貌似这次宏哥可能没空看题吧,我就帮宏哥补充一下:

使用where xxx in (select ...)的子查询SQL,在oracle上的确是效率比其它数据库都高(sql2000/2005/2008,mysql 5.0/5.1, sybase 10/11/12,oracle 8i/9i/10g/11g我都用过),可能是跟它有UNDOTBS这个设计有关(我猜的,一直都无法精通oracle, 另题外:oracle的复杂结构是有道理的,专用的多进程也是很有用的)

但类似

select * from topic where replyid in (select replyid from reply where replyAuthor like 'mike%' and (currentTime()-replyTime 

这种写法,更通常是写成left join方式:

select * from topic a

left join reply b on a.topicid=b.topicid where replyAuthor like 'mike%' and replyTime<(currentTime()-?)



这里的优化上要注意的是:

1.不能用(currentTime()-replyTime) > ? 的方式去比较时间,会造成计算字段无法使用索引的问题(任何关系数据库都是一样道理,包括最猛的oracle)

2.对replyAuthor 和 replyTime使用联合索引,这样可以在此查询中被优化器用上(但哪个在前哪个在后也有学问,自己深入后再研究吧)

至于设计,我个人觉得问题不大,这个设计已经很合理了。虽然关系数据库中有增加表设计冗余度来提高性能的做法,但以我的项目经验来说,先不说这种做法不能带来多少性能上巨大的提升,就说设计烂了要修正比数据库性能低下要优化来说难得多。

至于 mysql是不是支持事务,这个要视乎它使用哪个存储引擎而定,innodb, ndb都是支持事务的,可以由数据库层面确保满足事务一致性,而不需要应用程序额外的代码,在学习的态度上,兼听则明!

你观察的真仔细.我回头看看,表设计的确没有问题,如果能抽取 Author到独立表,就更好. 之前看到那个auto_increment 就么有兴趣继续看了. 冗余设计,任何时候都是不需要的.

再补充两个:

1:replyTime<(currentTime()-?)  这个你应该说对了,但是仍然取决于规划器. 规划器有可能实现你说的目标.

2: In 这种写法, 性能更高. 因为它已经取得一个小的结果集再做join 操作,而不是left jion.

3. 只提供思路. 必须在一个小的结果集上做 like操作. 或者只在Author表当中做like操作,取得Author结果集,再做 IN操作. 我怀疑考官的目的是要 建立表,记录Author

HelloChina
HelloChina
有帮助,谢谢了,等有分了补上
0
酒逍遥
酒逍遥

1.问从性能上考虑,这样做有什么不足。 

不足之处在于当主题数和回复数快速增长时..表的记录会无限增多最终导致查询会越来越慢。

可扩展性很差.


2.查询回复时间不超过一个特定的时间段,回复的作者名字以MIKE开头的主题 
   的title,以如下的查询: 
   select * from topic where replyid in (select replyid from reply where replyAuthor like 'mike%' and (currentTime()-replyTime   从性能上考虑上述的查询语句有什么不足? 

   如何进行优化?

性能上考虑,这条查询语句含有一个子查询.如果子查询查出的记录数比较多的话那么该语句效率会大大下降.而且取时间段的时候最好在程序中把时间段取好,不要在mysql中用函数和表达式,这会导致无法使用索引.

优化的话可以分成两条查询语句,先查出topicid,再查出主题的title

另外题目中的sql语句本身就是错误的语句

应该是 

select * from topic where topicId in (select topicId from reply where replyAuthor like 'mike%' and replyTime<currentTime()-time

currentTime()-time 表示特定时间段

酒逍遥
酒逍遥
回复 @xyz555 : 嗯 是的
xyz555
xyz555
回复 @酒逍遥 : 如果面试时不熟悉的或不知道的随便说,很容易把自己陷入被动。
酒逍遥
酒逍遥
回复 @xyz555 : 这应该是面试题..我说的是面试的技巧.当然也不一定对...这种问题要彻底解决是一个系统化的工程.不是三言两语说的清楚的..这里只是考查一下你的经验知识
xyz555
xyz555
回复 @酒逍遥 : 我知道“这么设计问性能上有什么不足.”数据库记录肯定都是无限增加的,除非废弃不用。这种“不足”(也不是不足)是无法解决的,你说来何用?“人家没问就不用详说了”呵呵,你这逻辑....无语
酒逍遥
酒逍遥
回复 @xyz555 : 注意看题目,这么设计问性能上有什么不足.这个就是不足啊.至于扩展性,是属于解决方案里的. 人家没问就不用详说了.
下一页
返回顶部
顶部