zoukankan      html  css  js  c++  java
  • sql语句优化总结

    sql语句优化总结

    数据库优化的几个原则:

    1.尽量避免在列上做运算,这样会导致索引失败;

    2.使用join是应该用小结果集驱动大结果集,同时把复杂的join查询拆分成多个query。不然join的越多表,就会导致越多的锁定和堵塞。

    3.注意like模糊查询的使用,避免使用%%,例如select * from a where name like '%de%';

    代替语句:select * from a where name >= 'de' and name < 'df';

    4.仅列出需要查询的字段,不要使用select * from ...,节省内存;

    5.使用批量插入语句,节省交互;

    insert into a (id ,name)
    values(2,'a'),
    (3,'s');

    6.limit基数比较大时,使用between ... and ...

    7.不要使用rand函数随机获取记录;

    8.避免使用null ,这就需要在建表时,尽量设置为not null,提升查询性能;

    9,不要使用count(id),而应该是count(*)

    10.不要做无谓的排序,尽可能在索引中完成排序;

    我们先来看一个sql:

     select
                        ii.product_id, 
                        p.product_name, 
                        count(distinct pim.pallet_id) count_pallet_id, 
                        if(round(sum(itg.quantity),2) > -1 && round(sum(itg.quantity),2) < 0.005, 0, round(sum(itg.quantity),2)) quantity,
                        round(ifnull(sum(itag.locked_quantity), 0.00000),2) locked_quantity,
                        pc.container_unit_code_name,
                        if(round(sum(itg.qoh),2) > -1 && round(sum(itg.qoh),2) < 0.005, 0, round(sum(itg.qoh),2)) qoh,
                        round(ifnull(sum(itag.locked_qoh), 0.00000),2) locked_qoh,
                        p.unit_code,
                        p.unit_code_name
                    from (select 
                            it.inventory_item_id item_id, 
                            sum(it.quantity) quantity, 
                            sum(it.real_quantity) qoh 
                        from 
                            ws_inventory_transaction it
                        where 
                            it.enabled = 1 
                        group by 
                            it.inventory_item_id  
                        ) itg 
                        left join (select 
                                        ita.inventory_item_id item_id, 
                                        sum(ita.quantity) locked_quantity, 
                                        sum(ita.real_quantity) locked_qoh 
                                   from 
                                        ws_inventory_transaction_action ita
                                   where 
                                        1=1 and ita.type in ('locked', 'release') 
                                   group by 
                                        ita.inventory_item_id 
                                   )itag on itg.item_id = itag.item_id
                        inner join ws_inventory_item ii on itg.item_id = ii.inventory_item_id 
                        inner join ws_pallet_item_mapping pim on ii.inventory_item_id = pim.inventory_item_id  
                        inner join ws_product p on ii.product_id = p.product_id and p.status = 'OK'
                        left join ws_product_container pc on ii.container_id = pc.container_id
    //总起来说关联太多表,设计表时可以多一些冗余字段,减少表之间的关联查询;
    where ii.inventory_type = 'raw_material' and ii.inventory_status = 'in_stock' and ii.facility_id = '25' and datediff(now(),ii.last_updated_time) < 3 //违反了第一个原则 and p.product_type = 'goods'
    and p.product_name like '%果%' // 违反原则3
    group by ii.product_id having qoh < 0.005 order by qoh desc

    上面的sql我们在from 中使用了子查询,这样对查询是非常不利的;

    更好的一种做法是下面的语句:

    select  
                    t.facility_id,
                    f.facility_name,
                    t.inventory_status,
                    wis.inventory_status_name,
                    t.inventory_type,
                    t.product_type,
                    t.product_id, 
                    p.product_name,
                    t.container_id, 
                    t.unit_quantity, 
                    p.unit_code,
                    p.unit_code_name,
                    pc.container_unit_code_name,
                    t.secret_key,
                    sum(t.quantity) quantity,
                    sum(t.real_quantity) real_quantity,
                    sum(t.locked_quantity) locked_quantity,
                    sum(t.locked_real_quantity) locked_real_quantity
                from ( select 
                            ii.facility_id,
                            ii.inventory_status,
                            ii.inventory_type,
                            ii.product_type,
                            ii.product_id, 
                            ii.container_id, 
                            ii.unit_quantity, 
                            ita.secret_key,
                            ii.quantity quantity,
                            ii.real_quantity real_quantity,
                            sum(ita.quantity) locked_quantity,
                            sum(ita.real_quantity) locked_real_quantity
                        from 
                            ws_inventory_item ii 
                            inner join ws_inventory_transaction_action ita on ii.inventory_item_id = ita.inventory_item_id
                        where 
                            ii.facility_id = '{$facility_id}' and 
                            ii.inventory_status = '{$inventory_status}' and 
                            ii.product_type = '{$product_type}' and 
                            ii.inventory_type = '{$inventory_type}' and
                            ii.locked_real_quantity > 0 and 
                            ita.type in ('locked', 'release') 
                        group by 
                            ii.product_id, ita.secret_key, ii.container_id, ita.inventory_item_id
                        having 
                            locked_real_quantity > 0 
                ) as t
                    inner join ws_product p on t.product_id = p.product_id 
                    left join ws_facility f on t.facility_id = f.facility_id
                    left join ws_inventory_status wis on wis.inventory_status = t.inventory_status
                    left join ws_product_container pc on pc.container_id = t.container_id            
                group by 
                    t.product_id, t.secret_key, t.container_id

    注意:

    1、from 语句中一定不要使用子查询;

    2、使用更多的where加以限制,缩小查找范围;

    3、合理利用索引;

    4、通过explain查看sql性能;

    相关优化可以借鉴:http://blog.csdn.net/csh624366188/article/details/8457749

  • 相关阅读:
    重测序(RADseq)做群体遗传分析套路
    BSA分析
    GWAS初探
    GWAS在农业上应用
    【Python小试】计算目录下所有DNA序列的Kmer并过滤
    dict['source'] = list[1],出现这种情况大多是数据的格式发生错误
    First Wainberg-2018-Deep learning in biomedicine Experience
    Second LearningConvolutionalNeuralNetworksforGraphs Experience
    从windows本地IDE启动远程Linux文件进行调试
    xshell的一些基本操作
  • 原文地址:https://www.cnblogs.com/sdgf/p/5659289.html
Copyright © 2011-2022 走看看