簡體   English   中英

使用以及WHERE和OR選擇左聯接

[英]SELECT LEFT JOIN with USING and WHERE AND OR

我正在嘗試以下SQL查詢來顯示來自mysql數據庫的搜索結果

這有效

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刪除:

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)lagerbestand(level, 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%');

這可能會更快,因為可能會更有效地優化子查詢。 您可以獨立嘗試每一個,以查看是否仍然存在性能問題。

如果我想返回上一個查詢中指定的集合,則我認為最佳性能的最佳選擇是將其分解為兩個不同的集合,然后將它們與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, ... )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM