数据库查询——性能调优~

飘过的小牛 2013-12-06 02:43:12
加精
现在项目出现了一个性能瓶颈:

我有A/B/C,3个表

现在通过B查询状态为1的记录,大概4000条。然后遍历这4000条:
在C表(50万记录)查找id和B表id相同的记录

所以,性能瓶颈就是C表根据id查询。所以需要执行4000次查询。再包括建立连接、断开连接之类的开销。现在完成这个模块大概需要4分钟左右。

我现在想优化的思路是这样:

通过1次查询把C表的信息全部读进内存。但是问题是,如果我没有任何处理就读取,那么返回的是List<Object>对象,我需要完成4000 * 50万遍历才能完成这个任务。这样就更悲剧了。 所以,我想
select * from C where id in (1,2,3,4,5,...4000); 然后把这些结果装到一个
HashMap<B表id, List<Object>>。这样我用到的时候根据id就可以拿。

不知道SimpleJdbcTemplate有这样的函数吗????在线急等~~~
...全文
4178 58 打赏 收藏 转发到动态 举报
写回复
用AI写文章
58 条回复
切换为时间正序
请发表友善的回复…
发表回复
New-Bee 2014-07-01
  • 打赏
  • 举报
回复
我们用的memcache,百万数据,轻松秒查,建议试试,还有,子查询,是效率最低的,建议不要用
jy02344406 2014-06-30
  • 打赏
  • 举报
回复
select * into #B from B where type=1 select t1.* from C t1,#B t2 where t1.id=t2.id 得到的数据集是符合条件的C表数据
楊松坤 2014-02-19
  • 打赏
  • 举报
回复
( > c < ) 哀哀叫! QQ:125004485
猪猪猪爱的 2014-01-23
  • 打赏
  • 举报
回复
引用 5 楼 acefr 的回复:
你那sql语句改成这个: select C.* from C where exists (select 1 from B where C.id=B.id)
两个表的id加上索引 不需要实时性 表名后加上(nolock) 不会有死锁问题 数据库只要是单独服务器即可 SQL楼主可以查看执行计划就可以优化很多 楼主的数据量不会超过1S才对 不建议楼主使用程序来做,程序这里楼主还需要考虑并发多线程的异常情况,加缓存等于是加了功能的复杂度。
lala123344 2013-12-15
  • 打赏
  • 举报
回复
真的吗????
kangxin8767 2013-12-13
  • 打赏
  • 举报
回复
试试5楼的吧 记得加索引
youhere1 2013-12-13
  • 打赏
  • 举报
回复
先Explain下看看是否使用了索引, 还有为什么需要实时建索引啊, 建索引前就应该考虑好哪些该建哪些不该建啊, 不应该把建立的权限放到程序里的. "固定时间就要更新一次" 这个的目的是防止索引空洞化的吧. 如果怕索引过多影响插入速度的话可以用读写分离的方式来建数据库.
IceSea7 2013-12-13
  • 打赏
  • 举报
回复
不会调试时硬伤啊
福清仔 2013-12-12
  • 打赏
  • 举报
回复
多写几个SQL语句,测试下选用最快的
wjlabc999 2013-12-12
  • 打赏
  • 举报
回复
多写几个SQL语句,测试下选用最快的
momoaiyanzi 2013-12-11
  • 打赏
  • 举报
回复
碰到效率问题。我一般都会想到空间和时间互换的理论。建立索引、调整数据库配置本质上都采用了这个方式。 如果c表主键是自增长的话,用id匹配是很快的。 我的想法是B表C表不直接关联。用一个tmp表格,这张表格只需要id字段,存储B表的状态有效的4000条id。关联tmp表和c表查询。这样数据量是4000×50万。这个数据量并不大,因为是主键的匹配,速度也很快。如果确实因为数据量大影响了响应时间,B表可以存储200条,然后循环20次。
StalvanMistmantle 2013-12-11
  • 打赏
  • 举报
回复
SELECT B.COLUMN1,B.COLUMN2....B.COLUMNX,B.ID, TEMP.COLUMN1,TEMP.COLUMN2...TEMP.COLUMNX FROM (SELECT C.COLUMN1 AS TEMP1,C.COLUMN2 AS TEMP2...C.COLUMNX AS TEMPN,C.ID AS TEMPID FROM C) AS TEMP ,B WHERE TEMP.ID = B.ID
fly518 2013-12-10
  • 打赏
  • 举报
回复
索引只要不是太多,性能影响不是太大的,好好使用数据库,这些算法人家都已经写好了,小数据量的话用nestloop join 搞定,数据量大的话用hash join搞定,比你自己造轮子快多了
tomash1989 2013-12-09
  • 打赏
  • 举报
回复
nice
vipqq010 2013-12-09
  • 打赏
  • 举报
回复
求指点啊- -
u013048151 2013-12-09
  • 打赏
  • 举报
回复
想学免杀,求高手的指点!
oh_Maxy 2013-12-09
  • 打赏
  • 举报
回复
引用 11 楼 niushuai666 的回复:
[quote=引用 6 楼 oh_Maxy 的回复:] 如果C表数据不怎么变化的话,可以考虑服务启动时,做个将C表加载到内存的任务,数据结构使用HashMap<B表id, List<Object>>,用的时候直接map.get(B表id)。 C表数据发生变化时,内存里的map对应的id对应的list也相应进行更新。 这要考虑内存,如果C表字段比较多,可能会占用很大内存。如果有条件,可以搞个缓存服务器。
现在用的就是这种方法!性能提升了50%。但是时间还是过长。大概需要100s的时间。我想优化到30s左右。因为我们现在服务器分布在3个机房,最初1个机房完成这个模块需要3分钟+、剩下2个因为网络都是10分钟+。现在估计情况是1分半、5分钟+ 目标是30s 3分钟。所以各位大拿有什么独门绝技,都秀出来吧!!! [/quote] 既然有条件搞分布式,应该考虑过缓存服务器吧?redis,把每次查询的数据缓存到缓存服务器中,根据不同表的使用情况,设置个有效时间。这个方案怎么样?
chuting1 2013-12-09
  • 打赏
  • 举报
回复
不错的东东,学习了
云满笔记 2013-12-09
  • 打赏
  • 举报
回复
数据库也能这么专业啊 惭愧啊
oh_Maxy 2013-12-09
  • 打赏
  • 举报
回复
共同学习啦~ 嗯,有索引、主键的时候,会影响插入的操作效率,有些项目因为增删操作非常频繁,就弃用索引了的。 不过不用主键、索引,错失浪费数据库的一大特性啊。
加载更多回复(36)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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