programing

JOIN이 WHERE보다 빠릅니까?

projobs 2021. 1. 15. 07:29
반응형

JOIN이 WHERE보다 빠릅니까?


연결된 두 개의 테이블이 있다고 가정합니다 (하나는 다른 하나에 외래 키가 있음).

CREATE TABLE Document (
  Id INT PRIMARY KEY,
  Name VARCHAR 255
)

CREATE TABLE DocumentStats (
  Id INT PRIMARY KEY,
  DocumentId INT, -- this is a foreign key to table Document
  NbViews INT
)

나는 이것이 일을하는 가장 현명한 방법은 아니지만 이것이 내가 생각 해낼 수있는 가장 좋은 예라는 것을 압니다.

이제보기가 500 개가 넘는 모든 문서를 가져오고 싶습니다. 내 마음에 떠오르는 두 가지 해결책은 다음과 같습니다.

SELECT *
FROM Document, DocumentStats
WHERE DocumentStats.Id = Document.Id
  AND DocumentStats.NbViews > 500

또는 :

SELECT *
FROM Document
INNER JOIN DocumentStats
ON Document.Id = DocumentStats.Id
WHERE DocumentStats.NbViews > 500

두 쿼리가 동일합니까, 아니면 다른 것보다 훨씬 나은 방법이 있습니까? 그렇다면 왜?

내 예제가 완벽하지 않고 쿼리에 약간의 조정이 필요할 수 있다는 것을 알고 있지만 요점을 알기를 바랍니다.)!

편집 : 답변에서 요청 한대로이 질문은 MSSQL을 대상으로했지만 다른 DB 엔진 (MySQL 등)과 다른지 아는 데 관심이 있습니다.


이론적으로는 더 빠르지 않아야합니다. 쿼리 최적화 프로그램은 동일한 실행 계획을 생성 할 수 있어야합니다. 그러나 일부 DB 엔진은 그중 하나에 대해 더 나은 실행 계획을 생성 할 수 있습니다 (이러한 단순한 쿼리에서는 발생하지 않을 가능성이 높지만 충분히 복잡한 경우). 둘 다 테스트하고 (DB 엔진에서) 확인해야합니다.


"JOIN"대 "WHERE"의 성능 ... 모든 것은 데이터베이스 엔진이 쿼리를 얼마나 잘 최적화 할 수 있는지에 달려 있습니다. 반환되는 열에있을 수있는 모든 인덱스를 고려하고 WHERE 및 JOIN 절의 성능이 실제 데이터베이스 파일 자체와 해당 조각화 수준, 심지어 데이터베이스 파일을 저장하는 데 사용하는 스토리지 기술까지 내려 간다는 점을 고려합니다. .

MSSql 서버는 다음 순서로 쿼리를 실행합니다 (이렇게하면 WHERE 및 JOIN 절의 기능에 대한 아이디어를 얻을 수 있음).

Microsoft SQL Server 쿼리 프로세스 순서

다음은 Microsoft SQL Server, Inside Microsoft SQL Server 2005 : T-SQL 쿼리 ( 여기 에서 찾을 수 있음)에 대한 훌륭한 책 시리즈에서 발췌 한 것입니다.

(Step 8) SELECT (Step 9) DISTINCT (Step 11)
(Step 1) FROM left_table
(Step 3) join_type JOIN right_table
(Step 2) ON join_condition
(Step 4) WHERE where_condition
(Step 5) GROUP BY group_by_list
(Step 6) WITH [CUBE | ROLLUP]
(단계 7) HAVING having_clause
(단계 10) ORDER BY order_by_list


대상 데이터베이스로 제한하지 않고이 문제에 올바르게 답할 수있는 방법은 없습니다.

MS-SQL의 경우 두 쿼리 모두 동일한 실행 계획을 생성하지만 다음 사항에 유의하십시오.

SELECT *
FROM Document, DocumentStats
WHERE DocumentStats.Id = Document.Id
  AND DocumentStats.NbViews > 500

WHERE 절에서 조인 조건을 잊고 불쾌한 교차 조인으로 끝나기 쉽기 때문에 정말 위험합니다.


적어도 MySQL에서는 둘 다 동일한 쿼리에 최적화됩니다.


INNER JOIN 구문을 사용하는 것은 거의 동일하지만 "표준"입니다. 사용되어야하는 주된 이유는 OUTER JOIN 구문과 일치하므로 명확성과 이동성을위한 것입니다.


Sqlite를 사용하는 경우 : Sqlite가 쿼리를 실행하기 전에 먼저 join-syntax를 where-syntax로 변환하기 때문에 where-syntax가 약간 더 빠릅니다.


SQL Server에 대해 구체적으로 이야기하는 경우 반드시 INNER JOIN 구문을 사용해야합니다. (개인 의견 경고!) 읽기 쉽고 의도가 명확하다는 것 외에도 SQL Server 2005부터는 외부 조인에 해당하는 구문이 없습니다. * = 및 = * 구문은 2005에서 기본적으로 지원되지 않습니다. 지원하려면 호환 모드를 활성화해야합니다. 아마도 다음 릴리스에서 곧 제거 될 것입니다.

이것은 다음을 의미합니다.

  • If you need to change a query from inner join to outer join, you need to either rewrite it (argh) or enable compat mode (yuk)
  • Without compat mode, you can't be consistent with how you implement different types of joins (inner vs outer), making for a maintenance nightmare (and, where the two are combined in the one query, some behaviour that's non-intuitive).

Note also that contrary to popular belief, the two are not equivalent. Some things are much more awkward, and some are simply not possible. Kalen Delaney's Inside SQL Server 2000 covers some examples; not sure if the newer editions do, because that join syntax is deprecated anyway.


Explicit joins are easier to maintain as the intent of the query is much clearer. Also they are not subject to accidental cross joins so if you have a cross join in the query, the maintainer knows it was intended to be there.

If you ever need to use outer joins, you should know that the *= syntax is deprecated in SQL Server and will soon be removed. Also it currently doesn't function as expected all the time and may not give correct results and thus should NEVER be used. Mixing explicit outer joins and where clause joins (implicit joins) makes a query much harder for a maintainer to read and understand.


In MSSQL, both queries are compiled to the same execution plan, so there's no difference. It's more about readability - I think the JOIN is easier to read, so I use that.


I guess that it doesn't make a difference too. To be sure you can check if the explain plan of those two queries is identical. In order to look at the explain plan in MySQL you have to put the "explain" keyword before the statement, eg:

EXPLAIN
SELECT *
FROM Document, DocumentStats
WHERE DocumentStats.Id = Document.Id
  AND DocumentStats.NbViews > 500

I'm sure there exists an equivalent in MSSQL too.

By the way: This looks like this is a 1:1 relationship so I'd just include the nbviews attribute directly in the Document table, therefore you can save a join.

ReferenceURL : https://stackoverflow.com/questions/1129923/is-a-join-faster-than-a-where

반응형