使用USING和WHERE AND OR选择LEFT JOIN

时间:2017-03-01 16:39:44

标签: php mysql sql select

我正在努力使用以下sql查询来显示来自mysql db的搜索结果

这有效

SELECT
    *
FROM
    lagerbestand
LEFT JOIN
    verkaufspreis USING (materialnummer)
WHERE
    lagerbestand.level='2' AND (lagerbestand.materialnummer='$suche' OR lagerbestand.materialkurztext LIKE '%$suche%')

这也有效

SELECT
    *
FROM
    lagerbestand
LEFT JOIN
    verkaufspreis USING (materialnummer)
WHERE
    lagerbestand.materialnummer='$suche' OR verkaufspreis.bezeichnung_fr LIKE '%$suche%'

但这不起作用

SELECT
    *
FROM
    lagerbestand
LEFT JOIN
    verkaufspreis USING (materialnummer)
WHERE
    lagerbestand.level='2' AND (lagerbestand.materialnummer='$suche' OR verkaufspreis.bezeichnung_fr LIKE '%$suche%')

唯一的区别是最后一点。

lagerbestand.materialkurztext已更改为verkaufspreis.bezeichnung_fr

然后脚本会永远加载。

2 个答案:

答案 0 :(得分:1)

我首先使用索引来加速查询。另外,如果没有必要,请从2删除引号:

SELECT *
FROM lagerbestand l LEFT JOIN
     verkaufspreis v
     USING (materialnummer)
WHERE l.level = 2 AND (l.materialnummer = '$suche' OR v.materialnummer LIKE '%$suche%');

对于此查询,您需要lagerbestand(level, bezeichnung_fr)verkaufspreis(materialnummer, bezeichnung_fr)上的索引。

我不保证这会带来很好的表现,但这是一个可以开始的地方。

编辑:

OR可能难以针对查询进行优化。下一个想法是使用union all

SELECT *
FROM lagerbestand l LEFT JOIN
     verkaufspreis v
     USING (materialnummer)
WHERE l.level = 2 AND l.materialnummer = '$suche'
UNION ALL
SELECT *
FROM lagerbestand l JOIN
     verkaufspreis v
     USING (materialnummer)
WHERE l.level = 2 AND (l.materialnummer <> '$suche' AND v.materialnummer LIKE '%$suche%');

这可能更快,因为子查询可能会更有效地进行优化。您可以单独尝试每个,以查看是否仍存在性能问题。

答案 1 :(得分:0)

如果我想返回上一个查询中指定的集合,我认为最佳性能的最佳选择是将其分解为两个不同的集合,并将它们与UNION ALL集合运算符组合。

(如果$such是要替换为SQL文本的变量,我会确保它在被包含之前已被正确转义。)

 SELECT l.*, v.*
   FROM lagerbestand l
   LEFT JOIN verkaufspreis v USING (materialnummer)
  WHERE l.level = '2'
    AND l.materialnummer = '$suche'

  UNION ALL

 SELECT l.*, v.*
   FROM lagerbestand l
   JOIN verkaufspreis v USING (materialnummer)
  WHERE l.level = '2'
    AND NOT ( l.materialnummer <=> '$suche' )
    AND v.bezeichnung_fr LIKE CONCAT('%','$suche','%')

然后我将使用EXPLAIN分别调整每个SELECT,确保有适当的索引。

 ON verkaufspreis (materialnummer, bezeichnung_fr, ... )

 ON lagerbestand (level, materialnummer, ... )