JOIN 쿼리 vs 여러 쿼리
JOIN 쿼리는 여러 쿼리보다 빠릅니까?(메인 쿼리를 실행하고 메인 쿼리의 결과에 따라 다른 많은 SELECT를 실행합니다.)
가입하면 내 애플리케이션 디자인이 복잡해질 것 같아서 물어보는 거야.
만약 그들이 더 빠르다면, 누구라도 대략 어느 정도 근사할 수 있을까요?1.5배면 상관없지만 10배면 상관없을 것 같아요.
내부 조인의 경우 일치하는 행만 가져오므로 단일 조회가 적합합니다.왼쪽 조인의 경우 여러 쿼리를 사용하는 것이 훨씬 좋습니다.다음 벤치마크를 살펴봅니다.
참가자가 5개인 단일 쿼리
쿼리: 8.074508초
결과 크기: 2268000
5회 연속 쿼리
조합 쿼리 시간: 0.00262초
결과 크기: 165(6+50+7+12+90)
.
두 경우 모두 동일한 결과를 얻을 수 있습니다(6 x 50 x 7 x 12 x 90 = 2268000).
왼쪽 조인은 다중 데이터로 기하급수적으로 더 많은 메모리를 사용합니다.
메모리 제한은 2개의 테이블만 결합하는 경우처럼 나쁘지 않을 수 있지만 일반적으로 3개 이상이면 다른 쿼리의 값이 됩니다.
참고로 MySQL 서버는 애플리케이션 서버 바로 옆에 있습니다.접속 시간은 무시할 수 있습니다.접속 시간이 초단위로 되어 있는 경우는, 아마 이점이 있습니다.
프랭크야.
이것은 당신의 구체적인 사례에 관련된 답변을 주기에는 너무 모호합니다.여러 가지에 따라 다르죠.Jeff Atwood(이 사이트의 설립자)가 실제로 이것에 대해 썼습니다.그러나 대부분의 경우 올바른 인덱스를 가지고 있고 JOIN을 적절하게 수행한다면 일반적으로 여러 번보다 한 번 실행하는 것이 더 빠릅니다.
이 질문은 오래되었지만 일부 벤치마크가 누락되어 있습니다.JOIN을 2개의 경쟁업체와 비교해서 벤치마킹했습니다.
- N+1 쿼리
- 의 쿼리,의 쿼리, , 2개의 쿼리가 사용됩니다.
WHERE IN(...)
한 것
합니다.MySQL에서는, 「MySQL 」입니다.MySQL 서 my myJOIN
훨씬 더 빠릅니다.N+1 쿼리는 응용 프로그램의 성능을 크게 떨어뜨릴 수 있습니다.
즉, 극소수의 서로 다른 외국 레코드를 가리키는 많은 레코드를 선택하지 않는 한,다음은 극단적인 경우의 벤치마크입니다.
이것은, 외부 키가 다른 테이블에 있어 메인 테이블 데이터를 여러 번 복제하고 있는, 다대다 관계에 참가하고 있지 않는 한, 일반적인 애플리케이션에서는 거의 발생하지 않습니다.
테이크 아웃:
- * 관계를 합니다.
JOIN
- *대다 관계의 경우 두 번째 쿼리가 더 빠를 수 있습니다.
자세한 것은, 「중간」의 기사를 참조해 주세요.
저는 실제로 답을 찾고자 이 질문에 대답했습니다. 그리고 주어진 답변을 읽은 후 DB 쿼리 성능을 비교하는 가장 좋은 방법은 고려해야 할 변수가 많기 때문에 실제 수치를 얻는 것이라는 것에 동의하는 것 밖에 할 수 없습니다. 그러나 이들 사이의 수치를 비교하는 것은 거의 모든 면에서 좋지 않다고 생각합니다.케이스.내 말은, 그 숫자들은 항상 허용 가능한 숫자와 비교되어야 하고 서로 절대 비교해서는 안 된다는 것이다.
예를 들어 0.02초, 20초 정도 걸리는 쿼리 방식이라면 큰 차이가 납니다.단, 한쪽 쿼리에는 0.0000000002초가 걸리고 다른 한쪽 쿼리에는 0.0000002초가 걸리면 어떻게 될까요?두 경우 모두 한 가지 방법이 다른 방법보다 무려 1000배 더 빠르지만, 두 번째 경우에서도 여전히 "와핑"하는 것일까요?
결론은 제가 개인적으로 봤을 때, 성능이 좋으면 쉬운 솔루션을 선택하라는 것입니다.
진짜 질문은: 이 레코드들이 일대일 관계인가, 일대다 관계인가 하는 것입니다.
TLDR 답변:
대 1 의 는, 1 의 1 을 사용합니다.JOIN
★★★★★★ 。
대 다일 경우 1 경우 1 대 다일 경우 1 대 다일 경우 1 을 합니다.SELECT
서버측 코드를 최적화한 스테이트먼트.
최적화에 SELECT를 사용하는 이유와 방법
SELECT
대해, 큰조인이 아닌 를 가지는 것)」을 1 대 다의 관계에 근거해 최적의 수 있습니다JOIN
ing에 기하급수적인 메모리 누전 문제가 있습니다.모든 데이터를 가져온 후 서버 측 스크립트 언어를 사용하여 데이터를 정렬합니다.
SELECT * FROM Address WHERE Personid IN(1,2,3);
결과:
Address.id : 1 // First person and their address
Address.Personid : 1
Address.City : "Boston"
Address.id : 2 // First person's second address
Address.Personid : 1
Address.City : "New York"
Address.id : 3 // Second person's address
Address.Personid : 2
Address.City : "Barcelona"
여기, 모든 기록을 하나의 엄선된 문장으로 가져옵니다. 낫습니다.JOIN
이러한 레코드의 작은 그룹을 다른 쿼리의 서브 컴포넌트로 한 번에 하나씩 가져옵니다.…
<?php
foreach($addresses as $address) {
$persons[$address['Personid']]->Address[] = $address;
}
?>
최적화에 JOIN을 사용하지 않는 경우
JOIN
에 근거해 하는 것은, 1개의 레코드가 1개의 레코드로 구성되어 있는 것과 비교하면, 수 있습니다SELECT
다음 레코드 타입을 얻을 수 있는 스테이트먼트를 차례로 나타냅니다.
★★★★★★★★★★★★★★★★★.JOIN
1대 다의 관계에서 레코드를 취득할 때는 비효율적입니다.
예:데이터베이스 블로그에는 블로그 포스트, 태그 및 주석의 3가지 관심 테이블이 있습니다.
SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;
블로그 포스트 1개, 태그 2개, 댓글 2개가 있으면 다음과 같은 결과를 얻을 수 있습니다.
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,
각 레코드가 어떻게 복제되는지 주목하십시오.네, 댓글 2개 태그 2개가 4줄이에요.댓글 4개랑 태그 4개면 어떡해?8개의 행이 아니라 16개의 행이 됩니다.
Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag1, comment3,
Row4: tag1, comment4,
Row5: tag2, comment1,
Row6: tag2, comment2,
Row7: tag2, comment3,
Row8: tag2, comment4,
Row9: tag3, comment1,
Row10: tag3, comment2,
Row11: tag3, comment3,
Row12: tag3, comment4,
Row13: tag4, comment1,
Row14: tag4, comment2,
Row15: tag4, comment3,
Row16: tag4, comment4,
테이블이나 레코드 등을 추가할 경우 문제는 대부분 중복 데이터로 가득 찬 수백 개의 행으로 빠르게 확대됩니다.
이 복제품들은 얼마예요?메모리(SQL 서버 및 중복 제거를 시도하는 코드)와 네트워킹 리소스(SQL 서버와 코드 서버 사이)
출처 : https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html
50,000개의 행 테이블에서 1개의 행을 선택하고 100,000개의 행 테이블에서 1개의 행으로 결합하는 간단한 테스트를 실시했습니다.기본적으로는 다음과 같습니다.
$id = mt_rand(1, 50000);
$row = $db->fetchOne("SELECT * FROM table1 WHERE id = " . $id);
$row = $db->fetchOne("SELECT * FROM table2 WHERE other_id = " . $row['other_id']);
대
$id = mt_rand(1, 50000);
$db->fetchOne("SELECT table1.*, table2.*
FROM table1
LEFT JOIN table1.other_id = table2.other_id
WHERE table1.id = " . $id);
2개의 선택 방식은 50,000회 읽기에 3.7초가 걸린 반면, 집에 있는 느린 컴퓨터에서는 JOIN에 2.0초가 걸렸습니다.이너 조인(Inner JOIN)과 좌측 조인(LEFT JOIN)은 차이가 없습니다.여러 행을 가져오면(예: IN SET 사용) 유사한 결과가 나왔다.
개별 쿼리와 결합을 모두 구성하고 각각의 시간을 설정합니다.실제 수치만큼 도움이 되는 것은 없습니다.
그러면 더 좋습니다. - 각 질의 시작 부분에 "설명"을 추가합니다.데이터 요청에 대한 응답에 MySQL이 사용하는 하위 쿼리 수와 각 쿼리에 대해 검색된 행 수를 알 수 있습니다.
개발자의 복잡성과 비교하여 데이터베이스의 복잡성에 따라 많은 SELECT 콜을 실행하는 것이 더 간단할 수 있습니다.
JOIN과 여러 SELECTS 모두에 대해 데이터베이스 통계 정보를 실행해 보십시오.고객님의 환경에서 JOIN이 SELECT보다 빠르거나 느린지 확인합니다.
또한 JOIN으로 변경하면 개발 작업이 하루/주/개월 더 필요할 경우 여러 SELECT를 사용할 수 있습니다.
건배.
BLT
지금까지의 경험으로는 특히 대용량 데이터 세트를 검색할 때 여러 쿼리를 실행하는 것이 일반적으로 더 빠르다는 것을 알게 되었습니다.
PHP와 같은 다른 응용 프로그램에서 데이터베이스와 상호 작용할 때 서버로의 1회 이동은 여러 번 반복해야 한다는 주장이 있습니다.
서버에 대한 트립 수를 제한하면서 여러 쿼리를 실행하는 다른 방법이 있습니다.이러한 쿼리는 고속일 뿐만 아니라 응용 프로그램을 읽기 쉽게 합니다.예를 들어 mysqli_multi_query 등입니다.
SQL에 관해서는 초보자가 아닙니다.개발자, 특히 후배들이 스마트해 보이기 때문에 매우 현명한 Join을 작성하기 위해 많은 시간을 소비하는 경향이 있다고 생각합니다만, 실제로는 단순해 보이는 데이터를 추출하는 스마트한 방법이 있습니다.
마지막 단락은 개인적인 의견이었지만, 이것이 도움이 되었으면 합니다.벤치마크를 해야 한다는 다른 사람들의 말에 동의합니다.어느 접근도 실탄은 아니다.
throughput이 더 빠를까요?아마 그럴 거예요.그러나 데이터베이스와 스키마에 따라 한 번에 더 많은 데이터베이스 개체를 잠글 수도 있으므로 동시성이 저하될 수 있습니다.제 경험상, 실제로는 데이터베이스가 같은 LAN 상에 있는 대부분의 OLTP 시스템에서 실제 병목현상은 거의 네트워크인 경우가 거의 없는데, 사람들은 종종 "더 적은 데이터베이스 라운드 트립"이라는 논리로 오해를 받습니다.
조인을 사용해야 하는지 여부는 조인이 적절한지 여부에 대한 가장 중요한 사항입니다.그 시점에서만 퍼포먼스가 고려 대상이 됩니다.그 외의 경우는 거의 모두 퍼포먼스가 현저하게 저하되기 때문입니다.
성능 차이는 주로 문의하는 정보의 관련성에 따라 달라집니다.작업에 참여하면 데이터가 관련되고 인덱싱이 올바르게 수행될 때 속도가 빠릅니다. 그러나 이러한 작업을 수행하면 일부 중복이 발생하고 때로는 필요 이상의 결과가 나타날 수 있습니다.데이터 세트가 직접 관련되지 않은 경우 단일 쿼리에 고정하면 데카르트 곱(기본적으로 행의 모든 가능한 조합)이라고 불리는 결과가 됩니다. 이는 거의 원하는 것이 아닙니다.
이것은 많은 경우 다대다 관계에 의해 발생합니다.예를 들어 HoldOffHunger의 답변에는 게시물, 태그 및 코멘트에 대한 단일 쿼리가 언급되어 있습니다.코멘트는 투고와 관련된 태그입니다.태그는 댓글과 관련이 없습니다.
+------------+ +---------+ +---------+
| comment | | post | | tag |
|------------|* 1|---------|1 *|---------|
| post_id |-----| post_id |-----| post_id |
| comment_id | | ... | | tag_id |
| user_id | | | | ... |
| ... | | | | ... |
+------------+ +---------+ +---------+
이 경우 이 쿼리는 적어도2개의 개별 쿼리로 하는 것이 좋습니다.태그와 코멘트를 결합하려고 하면 태그와 코멘트의 직접적인 관계가 없기 때문에 태그와 코멘트의 가능한 모든 조합이 됩니다. many * many == manymany
또, 투고와 태그는 관련성이 없기 때문에, 2개의 쿼리를 병행할 수 있기 때문에, 이익의 가능성이 있습니다.
다른 시나리오를 생각해 보겠습니다.코멘트를 투고에 첨부하고 코멘트의 연락처 정보를 원합니다.
+----------+ +------------+ +---------+
| user | | comment | | post |
|----------|1 *|------------|* 1|---------|
| user_id |-----| post_id |-----| post_id |
| username | | user_id | | ... |
| ... | | ... | +---------+
+----------+ +------------+
여기서 가입을 검토해야 합니다.MySQL을 포함한 대부분의 데이터베이스 시스템은 훨씬 자연스러운 쿼리일 뿐만 아니라 이와 같은 쿼리 최적화에 많은 노력을 기울이는 똑똑한 사람들이 있습니다.개별 쿼리의 경우 각 쿼리는 이전 쿼리의 결과에 따라 달라지기 때문에 쿼리를 병렬로 수행할 수 없으며 총 시간은 쿼리의 실제 실행 시간뿐만 아니라 결과를 가져오거나 다음 쿼리의 ID를 검색하거나 행을 서로 링크하는 데 걸리는 시간이 됩니다.
다음은 100개의 유용한 쿼리를 포함하는 링크입니다.이러한 쿼리는 Oracle 데이터베이스에서 테스트되지만 SQL은 표준이며 Oracle, MS SQL Server, MySQL 및 기타 데이터베이스의 차이점은 SQL 방언입니다.
http://javaforlearn.com/100-sql-queries-learn/
2진수 답이 없다는 것을 의미하는 몇 가지 요인이 있습니다.퍼포먼스에 최적인 것은 환경에 따라 다릅니다.덧붙여서, 식별자를 포함한 싱글 셀렉트가 초단위가 아닌 경우는, 설정에 문제가 있을 가능성이 있습니다.
진짜 질문은 데이터에 어떻게 액세스하느냐입니다.싱글 셀렉트 레이트바인딩을 지원합니다.예를 들어 직원 정보만 원하는 경우 직원 테이블에서 선택할 수 있습니다.외부 키 관계를 사용하여 나중에 필요에 따라 관련 리소스를 검색할 수 있습니다.선택 항목에는 이미 가리키는 키가 있기 때문에 매우 빨라야 하며 필요한 것만 가져오면 됩니다.네트워크 지연 시간을 항상 고려해야 합니다.
Joins는 모든 데이터를 한 번에 가져옵니다.보고서를 생성하거나 그리드를 채우는 경우 이것이 바로 원하는 것일 수 있습니다.이 시나리오에서는 컴파일 및 옵티마이즈된 결합이 단일 선택보다 더 빠릅니다.애드혹 조인은 그다지 빠르지 않을 수 있습니다.저장된 proc로 컴파일해야 합니다.빠른 답변은 실행 계획에 따라 달라집니다. 실행 계획에는 DBMS가 데이터를 검색하기 위해 수행하는 단계가 정확하게 설명되어 있습니다.
네, JOINS를 사용한1개의 쿼리가 더 빠릅니다.쿼리하는 테이블의 관계, 데이터 세트의 크기 또는 기본 키의 위치를 모르면 얼마나 빠른지 알 수 없습니다.
두 시나리오 모두 테스트해 보면 확실히 알 수 있을 거야
언급URL : https://stackoverflow.com/questions/1067016/join-queries-vs-multiple-queries
'programing' 카테고리의 다른 글
PHP에서 mysql_* 함수를 사용하면 안 되는 이유는 무엇입니까? (0) | 2022.09.12 |
---|---|
초기 렌더링 시 리액트 useEffect 후크를 실행하지 않도록 설정 (0) | 2022.09.12 |
마리아DB 루스터를 초기화할 때 백엔드 연결을 열지 못했습니다. -98(이미 사용 중인 주소) (0) | 2022.09.12 |
POST 요청 %5B 및 %5D는 무엇을 나타냅니까? (0) | 2022.09.12 |
_(언더스코어)는 예약된 키워드입니다. (0) | 2022.09.12 |