안녕하세요. 쿼리/PHP 조합을 효율적으로 실행하는 데 문제가 있습니다. 내 PHP에서 내부 루프에 너무 많은 결과 집합을 반복하는 것 같습니다. 이렇게하는 것이 더 효율적인 방법이라고 확신합니다. 어떤 도움이라도 대단히 감사합니다.
rid | recipe_name
레시피에 성분이 포함되어 있는지 확인 - MYSQL
그리고 600 개 가지 성분 ([재료])
iid | i_name
각을 보유하고 다른 테이블 :
나는 3500 개 요리법 ([레시피]) 보유하고 테이블을 가지고있다 조리법에 x 개의 재료가 연결되어 있으며 좋은 조인 테이블을 사용하여 연관성을 만듭니다 ([recipe_ingredients])
uid | rid | iid
01 예를 들어
(UID 테이블 단지 고유 한 ID입니다) 23,516,는 :
는
rid: 1 | recipe_name: Lemon Tart
.....
iid: 99 | i_name: lemon curd
iid: 154 | i_name: flour
.....
1 | 1 | 99
2 | 1 | 154
내가 실행하는 데 노력하고있어 쿼리는 사용자들이 가지고있는 성분을 입력 할 수 있습니다, 그것은 것입니다 당신이 그 성분으로 만들 수있는 것을 말해주십시오. 그것은 모든 재료를 사용하지 않아도되지만 조리법에 필요한 모든 재료가 있어야합니다.
예를 들어 밀가루, 계란, 소금, 우유 및 레몬 커드가 있다면 '레몬 케이크'(레몬 타트는 다른 성분이 없다고 가정하면 :)) 만들 수는 없습니다. 'Risotto'(내가 didnt하는 것에 따라 어떤 쌀이나 그것에서 필요로하게되는 그 것이있다).
내 PHP에는 사용자가 가지고있는 모든 성분이 들어있는 배열이 있습니다. 현재 내가 실행하고있는 방식대로 모든 레서피 (루프 1)를 통과 한 다음 해당 레시피의 모든 성분을 확인하여 각 성분이 제 성분 계획 (루프 2)에 포함되어 있는지 확인합니다. 레시피에서 성분을 발견하자마자, 그것은 내 배열에있는 것이 아니며, "아니오"라고 말하고 다음 레시피로갑니다. 그럴 경우, 새로운 배열에 rid를 저장하고 나중에 그 결과를 표시합니다.
그러나 효율성을 보면 3500 개의 레시피가 있고 40 개의 구성 요소가 배열에 포함되어있는 경우 최악의 시나리오는 3500 x 40n을 실행하는 것입니다. 여기서 n은 레시피의 재료 수입니다 . 가장 좋은 경우는 여전히 3500 x 40입니다 (모든 제조법에 대해 재료가 처음 나오지는 않습니다).
내 모든 접근 방식이 잘못되었다고 생각하며 여기에 실종 된 영리한 SQL이 있어야한다고 생각합니다. 이견있는 사람?
select recipes.rid, count(recipe_ingredients.iid) as cnt
from recipes
left join recipe_ingredients on recipes.rid = recipe_ingredients.rid
where recipes_ingredients in any (the,list,of,ingredients,the,user,hash)
group by recipes.rid
having cnt > some_threshold_amount
order by cnt desc
: 난 항상 ...... 내가 가지고있는 성분 배열에서
덕분에 많은
그래, 실제로 레시피의 성분 수를 테이블에 저장하고 정규화 (또는 부족)에주의해야합니다. "ing"생성 된 테이블에서 쿼리를 읽는 것으로부터 완전히 확신 할 수는 없지만 실행하고 알립니다 .... –
ing 테이블의 조인은 재료 목록을 필터링하는 방법입니다. 내부 조인이므로 사용자가 제공하는 목록과 일치하지 않는 모든 요리법이 중단되고 다른 재료에 조제 할 필요가 없습니다. – schizodactyl
다른 곳에서 논의 된 것과 같은 IN ANY 쿼리를 사용할 수 있지만 실행 속도가 중요하다면 쿼리가 동일 할 것이라는 점에 유의하십시오. 대부분 의미가 있습니다. 준비된 문장은 재료의 수가 다양하기 때문에 당신의 경우에 그렇게 유용하지는 않지만 준비된 문장과 함께 사용할 수 없기 때문에 모든 쿼리를 피하는 경향이 있습니다. – schizodactyl