[英]SELECT LEFT JOIN with USING and WHERE AND OR
I'm struggling with the following sql query to display a search result from a mysql db 我正在尝试以下SQL查询来显示来自mysql数据库的搜索结果
This works 这有效
SELECT
*
FROM
lagerbestand
LEFT JOIN
verkaufspreis USING (materialnummer)
WHERE
lagerbestand.level='2' AND (lagerbestand.materialnummer='$suche' OR lagerbestand.materialkurztext LIKE '%$suche%')
This works too 这也有效
SELECT
*
FROM
lagerbestand
LEFT JOIN
verkaufspreis USING (materialnummer)
WHERE
lagerbestand.materialnummer='$suche' OR verkaufspreis.bezeichnung_fr LIKE '%$suche%'
But this doesn't work 但这行不通
SELECT
*
FROM
lagerbestand
LEFT JOIN
verkaufspreis USING (materialnummer)
WHERE
lagerbestand.level='2' AND (lagerbestand.materialnummer='$suche' OR verkaufspreis.bezeichnung_fr LIKE '%$suche%')
The only difference is the last bit. 唯一的不同是最后一点。
lagerbestand.materialkurztext is changed to verkaufspreis.bezeichnung_fr lagerbestand.materialkurztext更改为verkaufspreis.bezeichnung_fr
Then the script just loads for ever. 然后脚本将永远加载。
I would start by using indexes to speed the query. 我将从使用索引加快查询速度开始。 Also, drop the quotes from 2
if it is not necessary: 另外,如果没有必要,请将引号从2
删除:
SELECT *
FROM lagerbestand l LEFT JOIN
verkaufspreis v
USING (materialnummer)
WHERE l.level = 2 AND (l.materialnummer = '$suche' OR v.materialnummer LIKE '%$suche%');
For this query, you want an index on lagerbestand(level, bezeichnung_fr)
and verkaufspreis(materialnummer, bezeichnung_fr)
. 对于此查询,您需要在lagerbestand(level, bezeichnung_fr)
和verkaufspreis(materialnummer, bezeichnung_fr)
上lagerbestand(level, bezeichnung_fr)
索引。
I'm not guaranteeing this will result in great performance, but it is a place to start. 我不保证这会带来出色的性能,但这是一个起点。
EDIT: 编辑:
OR
can be hard to optimize for a query. OR
可能难以优化查询。 The next idea is to use union all
: 下一个想法是使用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%');
This might be faster, because the subqueries might be optimized more efficiently. 这可能会更快,因为可能会更有效地优化子查询。 You can try each one independently to see if there still a performance problem. 您可以独立尝试每一个,以查看是否仍然存在性能问题。
If I wanted to return set specified in the last query, I think the best bet for optimal performance is going to be to break that up into two distinct sets, and combine those with a UNION ALL set operator. 如果我想返回上一个查询中指定的集合,则我认为最佳性能的最佳选择是将其分解为两个不同的集合,然后将它们与UNION ALL集合运算符组合。
(If $such
is meant to be variable that is substituted into the SQL text, I would make sure that it has been properly escaped, before it is included.) (如果$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','%')
Then I would tune each of those SELECT separately, using EXPLAIN
, making sure appropriate indexes are available. 然后,我将使用EXPLAIN
分别调整每个SELECT,以确保可以使用适当的索引。
ON verkaufspreis (materialnummer, bezeichnung_fr, ... )
ON lagerbestand (level, materialnummer, ... )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.