2014-03-05 105 views
0

我有一个小问题,我无法环绕我的头。MySQL IN子句太慢,无法加入JOIN以正常工作

这个查询完全符合我的需要,只需要永久性地杀死mysql守护进程。

"SELECT * 
FROM inventory 
WHERE 
    mac LIKE '%".$s."%' 
    OR uid IN (SELECT id FROM clients WHERE username LIKE '%".$s."%')" 

正确的方法是去JOIN子句,但不幸的是我不能得到它的工作。

基本上,我试图搜索两个表,然后根据mac地址或用户名选择记录。

任何帮助,将不胜感激!

+1

也是“任何%”是一个性能杀手 – Strawberry

+0

@Strawberry:...还有'或' – zerkms

+0

你能不能在其他列搜索?有时我会创建额外的人造色谱柱来帮助搜索。 –

回答

1

这里有一个办法:

"SELECT i.* 
    FROM inventory i 
    LEFT 
    JOIN (SELECT c.id 
      FROM clients c 
      WHERE c.username LIKE '%".$s."%' 
      GROUP BY c.id 
     ) v 
    ON v.id = i.uid 
    WHERE i.mac LIKE '%".$s."%' 
    OR v.id IS NOT NULL" 

不是重新执行每个IN(子查询),每行的库存表这应该是显著更有效。但是查询仍然存在问题,因为它必须对inventoryclients表中的每一行执行全面扫描。

+0

这很好用!不幸的是,我还是无法赞成......非常感谢! – user2446837

0
SELECT inventory.* 
FROM inventory LEFT JOIN clients ON (inventory.uid=clients.id) 
WHERE 
    mac LIKE '%".$s."%' OR username LIKE '%".$s."%' 
+0

只是几个笔记;在OP查询中,它仅从'库存'返回列;这个查询返回'inventory'和'clients'表中的列。另外,如果'clients'中有多于一行与'inventory.uid'匹配,那么这将从库存中返回“重复”行。 (OP查询不这样做。)在主键(或其他唯一的非空列)上添加GROUP BY将消除生成的重复项。 – spencer7593

+0

'uid'是'clients'表主键'id'的外键。作为一个主要关键,根据定义它将是唯一的,所以没有问题。 –

+0

我完全错过了'id'列被定义为'inventory'的主键。 – spencer7593