loading请求处理中...

SQL优化引发的思考

2021-12-02 05:48:25 阅读 10764次 标签: c#开发基础 作者: 蓝blue

      最近在做一个项目,在做查询数据库(oracle)中发现一个问题,当在测试环境下可以执行,但是当发布到生产环境上的时候,因为实际数据库量很大,导致sql执行很慢,架构给出的方案是做物化视图,因为查询的另外的几个表的数据在别的数据库中,但是为了保持数据同步,每隔一个小时更新一次,这样因为数据量太大导致oracle的日志隔天就满了,最终导致系统卡死,关键的是卡死的时候正好在给客户的领导演示,这样真的很尴尬...

SQL优化引发的思考

     经过以上操作,我通过在实际环境中运行sql发现,有以下几种状态容易引发,因为是做的统计查询,所以有些计算,截取前几位等操作:a : group by;

                   b : s elect * f rom () where rownum>100;

                   c : aa表 full join bb表;

     因为sql的查询和计算的数据量很大,有一个表数据是2000万以上,两个表的数据量为600万以上,查询的时间在一分钟以上,有的sql直接报错。

    解决方案:a : 在查询之后group by 不用了,直接查询出结果,之后再用java代码实现根据某个字段对结果list进行分组,再次                     返回另一个list:

                    代码:

          

[java] view plain copy
  1. package test;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6. import java.util.Map.Entry;  
  7. import java.util.TreeMap;  
  8.   
  9. class JavaBean {  
  10.     public JavaBean(String id, String name) {  
  11.         this.id = id;  
  12.         this.name = name;  
  13.     }  
  14.    
  15.     private String id;  
  16.    
  17.     public String getId() {  
  18.         return id;  
  19.     }  
  20.    
  21.     public void setId(String id) {  
  22.         this.id = id;  
  23.     }  
  24.    
  25.     public String getName() {  
  26.         return name;  
  27.     }  
  28.    
  29.     public void setName(String name) {  
  30.         this.name = name;  
  31.     }  
  32.    
  33.     private String name;  
  34.    
  35.     public JavaBean() {  
  36.     }  
  37.    
  38.     @Override  
  39.     public String toString() {  
  40.         // TODO Auto-generated method stub  
  41.         return "{用户ID:" + this.id + ",  用户名:" + this.name + " }";  
  42.     }  
  43.   
  44.    
  45. public static void main(String[] args) {  
  46.         //向list中添加对象   
  47.         List list = new ArrayList();  
  48.         list.add(new JavaBean("1010""admin"));  
  49.         list.add(new JavaBean("1010""admin"));  
  50.         list.add(new JavaBean("1020""xiaohua"));  
  51.         for(int i =0;i<5000;i++){  
  52.             list.add(new JavaBean("1020""xiaohua"));  
  53.              list.add(new JavaBean("1010""admin"));  
  54.         }  
  55.         list.add(new JavaBean("1020""xiaohua"));  
  56.         List> groupList = getListByGroup(list);  
  57.         for (List bean : groupList) {  
  58.             System.out.println(bean);  
  59.         }  
  60.         if("1010".equals(groupList.get(0).get(0).getId())){  
  61.             System.out.println( "1010:"+groupList.get(0).size());  
  62.         }  
  63.         if("1020".equals(groupList.get(1).get(0).getId())){  
  64.             System.out.println("1020:"+groupList.get(1).size());  
  65.         }  
  66.     }  
  67.    
  68.     private static List> getListByGroup(List list) {  
  69.         List> result = new ArrayList>();  
  70.         Map> map = new TreeMap>();  
  71.    
  72.         for (JavaBean bean : list) {  
  73.             if (map.containsKey(bean.getId())) {  
  74.                 List t = map.get(bean.getId());  
  75.                 t.add(new JavaBean(bean.getId(), bean.getName()));  
  76.                 new ArrayList().add(new JavaBean(bean.getId(), bean  
  77.                         .getName()));  
  78.                 map.put(bean.getId(), t);  
  79.             } else {  
  80.                 List t = new ArrayList();  
  81.                 t.add(new JavaBean(bean.getId(), bean.getName()));  
  82.                 map.put(bean.getId(), t);  
  83.             }  
  84.         }  
  85.         for (Entry> entry : map.entrySet()) {  
  86.             result.add(entry.getValue());  
  87.         }  
  88.         return result;  
  89.     }  
  90. }  

    b: 新建一个list往里面注入当前list的前100个元素;

     但是有的时候要排序,order by 一下,此时也容易导致sql速度变慢:

    解决:

    一个javabean:

[java] view plain copy
  1. package test;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class TDate {  
  6.     private String str;  
  7.     private Date date;  
  8.     public String getStr() {  
  9.         return str;  
  10.     }  
  11.     public void setStr(String str) {  
  12.         this.str = str;  
  13.     }  
  14.     public Date getDate() {  
  15.         return date;  
  16.     }  
  17.     public void setDate(Date date) {  
  18.         this.date = date;  
  19.     }  
  20.     @Override  
  21.     public String toString() {  
  22.         return "TDate [str=" + str + ", date=" + date + "]";  
  23.     }  
  24.       
  25.   
  26. }  

  比较方法:包含一个String 字符串转换成时间:来对时间进行比较的java方法:

[java] view plain copy
  1. package test;  
  2.   
  3. import java.text.DateFormat;  
  4. import java.text.ParseException;  
  5. import java.text.SimpleDateFormat;  
  6. import java.util.ArrayList;  
  7. import java.util.Collections;  
  8. import java.util.Comparator;  
  9. import java.util.Date;  
  10. import java.util.List;  
  11.   
  12. public class DateFoemate {  
  13.     public static void main(String[] args) throws ParseException {  
  14.            
  15.         List list = new ArrayList();  
  16.         TDate tDate1 = new TDate();  
  17.         tDate1.setStr("2018-02-25");  
  18.         list.add(tDate1);  
  19.         TDate tDate2 = new TDate();  
  20.         tDate2.setStr("2018-02-26");  
  21.         list.add(tDate2);  
  22.         TDate tDate3 = new TDate();  
  23.         tDate3.setStr("2018-12-27");  
  24.         list.add(tDate3);  
  25.         TDate tDate4 = new TDate();  
  26.         tDate4.setStr("2018-02-28");  
  27.         list.add(tDate4);  
  28.         TDate tDate5 = new TDate();  
  29.         tDate5.setStr("2018-05-01");  
  30.         list.add(tDate5);  
  31.         TDate tDate6 = new TDate();  
  32.         tDate6.setStr("2018-03-03");  
  33.         list.add(tDate6);  
  34.         TDate tDate7 = new TDate();  
  35.         tDate7.setStr("2018-04-09");  
  36.         list.add(tDate7);  
  37.         TDate tDate8 = new TDate();  
  38.         tDate8.setStr("2018-02-01");  
  39.         list.add(tDate8);  
  40.         TDate tDate9 = new TDate();  
  41.         tDate9.setStr("2018-02-20");  
  42.         list.add(tDate9);  
  43.         TDate tDate10 = new TDate();  
  44.         tDate10.setStr("2018-03-20");  
  45.         list.add(tDate10);  
  46.           
  47.          DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");  
  48.          Date date = null;  
  49.            
  50.          for(TDate tDate : list){  
  51.              date = format1.parse(tDate.getStr());   
  52.              tDate.setDate(date);  
  53.          }  
  54.         Collections.sort(list, new Comparator(){  
  55.   
  56.             @Override  
  57.             public int compare(TDate o1, TDate o2) {  
  58.                 if(o2.getDate().before(o1.getDate()) ){  
  59.                     return 1 ;  
  60.                 }  
  61.                 if(o2.getDate().equals(o1.getDate())){  
  62.                     return 0;  
  63.                 }  
  64.                   
  65.                 return -1;  
  66.             }  
  67.               
  68.         });  
  69.            
  70.          System.out.println(list);  
  71.            
  72.     }  
  73. }  

c:  单独建立aa表sql的返回list和bb表sql的返回list,再根据对应的主键将bb表的字段注入到aa表,如此可以拼接一个新的list,相当于full join的查询效果。

     因为查询结果后,java的运算比oracle的运算效率快很多,这样就可以解决以上问题。

开发公司推荐

成为一品威客服务商,百万订单等您来有奖注册中

留言( 展开评论

快速发任务

价格是多少?怎样找到合适的人才?

官方顾问免费为您解答

 
相关任务
DESIGN TASK 更多
可视化展示工具,开发

¥1000 已有2人投标

H5小游戏开发

¥10000 已有1人投标

归寝签到软件开发

¥5000 已有1人投标

ToG业务销售拓展管理系统开发

¥20000 已有1人投标

监控工具开发

¥15000 已有0人投标

微信营销平台开发

¥20000 已有4人投标

打窝船PCBA方案开发

¥3000 已有0人投标