当前位置: 代码迷 >> Sql Server >> 大神们帮忙优化一下小弟我的SQL,主要是OR有关问题,小弟我想用union 来替代,不过left join 这种如何用
  详细解决方案

大神们帮忙优化一下小弟我的SQL,主要是OR有关问题,小弟我想用union 来替代,不过left join 这种如何用

热度:46   发布时间:2016-04-24 09:11:54.0
大神们帮忙优化一下我的SQL,主要是OR问题,我想用union 来替代,不过left join 这种怎么用啊
原生SQL:
select DISTINCT c.id,c.url,c.shop_name,c.taobao_seller,c.credit,c.favorable,c.dsr,c.address,c.amount,c.sale_in_month,c.main_product,c.set_shop,c.phone,c.collection from ph_content c  left join ph_search b  on b.content_id = c.id,ph_search_unbind u  where  (b.id is null or b.parent_id != 1 ) and u.content_id=c.id and c.phone like ?  and (   main_product like ‘%女装%’ )  order by u.create_time limit 1,50



问题的症结所在就是b.id is null or b.parent_id != 1这段之中的OR,能不能将这个OR优化一下。
------解决思路----------------------
一般id是不能为null的,所以这两个条件可以理解为:
b.id is null c记录没有对应的b记录(还是输出c记录)
b.parent_id != 1 如果c记录有对应的b记录,并且b.parent_id 不是 1的才输出。
可以把where条件移到连接条件中
...
left join ph_search b
       on b.content_id = c.id,ph_search_unbind u
      and b.parent_id != 1
where  u.content_id=c.id ...

------解决思路----------------------
更正:#2的 ,ph_search_unbind u要移到and b.parent_id != 1后面

可以这样试试,先处理好b、c的关系,再做其它处理。
我倒是觉得其实两个like会比较费时,所以先缩小c的范围。

    SELECT c.*
      FROM (
            select c1.*
              from ph_content c1
             where not exists (select *
                                 from ph_search
                                where content_id = c1.id)
            UNION ALL
            select c2.*
              from ph_content c2
             where exists (select *
                             from ph_search
                           where content_id = c2.id
                             and parent_id != 1)

              left join ph_search b
                     on b.content_id = c.id
           ) c
          ,ph_search_unbind u
    where u.content_id=c.id
      and c.phone like ?
      and (main_product like '%女装%' )
 order by u.create_time limit 1,50

------解决思路----------------------
你的意思是 b.id is null AND b.parent_id != 1 的速度很快?
我猜测这个条件没有结果

另外,我想可以尝试把b.parent_id = 1 写到左连接上去

然后,WHERE这边只要判断b.id is null就可以了
------解决思路----------------------
我没有要删除,移地而已,逻辑应该是一样的,你尝试一下

把b.parent_id = 1 写到左连接上去,这个条件取反放在左连接

然后,WHERE这边只要判断b.id is null就可以了 ,这边统计取空,就把上面的条件也涵盖了
------解决思路----------------------
有没有可能问题出在!=1 上面?
------解决思路----------------------
where  (b.id is null or b.parent_id > 1 or b.parent_id <1 ) 

试试看。
------解决思路----------------------
SELECT DISTINCT
  c.id,
  c.url,
  c.shop_name,
  c.taobao_seller,
  c.credit,
  c.favorable,
  c.dsr,
  c.address,
  c.amount,
  c.sale_in_month,
  c.main_product,
  c.set_shop,
  c.phone,
  c.collection
FROM ph_content c
  LEFT JOIN ph_search b
    ON b.content_id = c.id AND b.parent_id = 1,
  ph_search_unbind u
WHERE b.id IS NULL
    OR u.content_id = c.id
    AND (main_product LIKE "%女装%")
ORDER BY u.create_time
LIMIT 1,20
b.parent_id = 1 相对于 b.parent_id != 1已经取反
你试下,你这个不是MSSQL我不确定可不可行
与后面表ph_search_unbind的连接方式及LIMIT是我的不确定因素,其它的应该和MSSQL差别不大
------解决思路----------------------
我#2已经给了移到连接中的方式,没反馈啊。
按照#3更正再贴一次(左连接是不需要特意判断b.id IS NULL的)
...
left join ph_search b
       on b.content_id = c.id
      and b.parent_id != 1
         ,ph_search_unbind u
    where u.content_id=c.id
      and c.phone like ?
      and (main_product like '%女装%' )
...
  相关解决方案