제품 및 제품 범주에 2 개의 테이블이 있다고 가정합니다. 두 테이블 모두 CategoryId에 관계가 있습니다. 그리고 이것은 쿼리입니다.
SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category
FROM Products p
INNER JOIN ProductCategories c ON p.CategoryId = c.CategoryId
WHERE c.CategoryId = 1;
실행 계획을 만들 때 Product Categories 테이블은 예상대로 클러스터 인덱스 검색을 수행합니다. 그러나 테이블 제품의 경우 클러스터 인덱스 스캔을 수행하므로 의심의 여지가 있습니다. FK가 쿼리 성능 향상에 도움이되지 않는 이유는 무엇입니까?
따라서 Products.CategoryId에 인덱스를 만들어야합니다. 실행 계획을 다시 만들면 두 테이블 모두 인덱스 검색을 수행합니다. 그리고 예상되는 서브 트리 비용이 많이 줄어 듭니다.
내 질문은 :
-
FK 외에도 관계 제한에 도움이되지만 다른 유용성이 있습니까? 쿼리 성능이 향상됩니까?
-
모든 테이블의 모든 FK 열 (예 : Products.CategoryId)에 인덱스를 만들어야합니까?
답변
외래 키는 성능 도구가 아닌 참조 무결성 도구입니다. 적어도 SQL Server에서 FK를 만들면 연결된 인덱스가 만들어지지 않으며 조회 시간을 향상시키기 위해 모든 FK 필드에 인덱스를 만들어야합니다.
답변
외래 키는 성능을 향상시키고 상처를 줄 수 있습니다
-
여기에 언급 된 바와 같이 : 외래 키는 성능 향상
-
조회를 줄이려면 항상 FK 열에 색인을 작성해야합니다. SQL Server는이를 자동으로 수행하지 않습니다.
편집하다
이제 링크가 작동하지 않는 것처럼 보이 므로 (크리스마스에게 알려야 함) 다음은 외래 키가 성능을 향상시키고 손상시킬 수있는 이유를 보여줍니다.
외래 키 제약 조건은 데이터를 읽을 때 성능을 향상시키는 동시에 데이터를 삽입 / 수정 / 삭제할 때 성능을 저하시킵니다.
쿼리를 읽는 경우 최적화 프로그램은 외래 키 제약 조건이 미리 선언 된 규칙이므로 외래 키 제약 조건을 사용하여보다 효율적인 쿼리 계획을 만들 수 있습니다. 예를 들어 옵티마이 저가 외래 키 제약 조건으로 인해 계획의 특정 부분을 실행할 필요가 없다는 것을 알 수 있기 때문에 일반적으로 쿼리 계획의 일부를 건너 뜁니다.
답변
외래 키는 데이터베이스 무결성을 보장하기위한 DBMS 개념입니다.
모든 성능 관련 / 개선 사항은 사용중인 데이터베이스 기술에 따라 다르며 외래 키의 목적에 부차적입니다.
SQL Server에서는 모든 외래 키에 클러스터되지 않은 인덱스가 적어도 있는지 확인하는 것이 좋습니다.
이 문제가 해결되기를 바랍니다. 자세한 내용은 언제든지 문의하십시오.
답변
가장 좋은 방법은 자주 사용하는 필드에서 색인을 사용하는 것입니다. SQL Server를 사용하는 경우 프로파일 러를 사용하여 특정 데이터베이스를 프로파일 링하고 출력하는 파일을 가져오고 튜닝 마법사를 사용하여 인덱스를 배치 할 위치에 대한 권장 사항을받을 수 있습니다. 또한 프로파일 러를 사용하여 장기 실행 저장 프로 시저를 플러시하는 것을 좋아합니다. 매주 게시하는 10 가지 최악의 범죄자 목록이 있습니다.
답변
쿼리를보다 효율적으로 만드는 데 사용할 수 있습니다. SQL Server에서 쿼리를 재구성하여 내부 조인 대신 외부 조인을 사용하여 SQL 서버에서 열에 null이 있는지 확인해야하는 필요성을 제거 할 수 있습니다. 외래 키 관계에 의해 이미 자격이 부여되므로 한정자를 넣을 필요가 없습니다.
그래서 이거:
select p.ProductId, p.Name, c.CategoryId, c.Name AS Category
from Products p inner join ProductCategories c on p.CategoryId = c.CategoryIdwhere c.CategoryId = 1;
이것이된다 :
SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category
FROM ProductCategories c
LEFT OUTER JOIN Products P ON
c.CategoryId = p.CategoryId
WHERE c.CategoryId = 1;
작은 쿼리에서 반드시 큰 성능을 발휘할 필요는 없지만 테이블이 커지면 더 효율적일 수 있습니다.
답변
MySQL 5.7의 경우 여러 조인과 관련된 쿼리 속도를 확실히 향상시킬 수 있습니다!
쿼리를 이해하기 위해 ‘explain’을 사용했으며 키가 전혀 사용되지 않은 4-5 테이블을 조인하고 있음을 발견했습니다. 이 테이블에 외래 키를 추가하는 것 외에는로드 시간이 90 % 단축되었습니다. 5 초 이상 걸린 쿼리는 이제 500ms 이하가 소요됩니다.
그것은 엄청나게 향상되었습니다!
그리고 다른 사람들이 언급했듯이 관계 무결성을 보장하는 추가 보너스를 얻습니다.
이 외에도 참조 무결성을 보장하는 것 자체 성능 이점도 있습니다. 외래 키가있는 테이블이 외래 테이블과 함께 ‘최신’이되도록하는 2 차 효과가 있습니다. 사용자 테이블과 주석 테이블이 있고 주석 테이블에 대한 통계를 수행한다고 가정하십시오. 사용자를 강제로 삭제하면 해당 사용자의 의견도 더 이상 원하지 않을 것입니다.
답변
테이블에 외래 키를 추가해도 성능이 향상되지 않습니다. 단순히 Product Categories 테이블 데이터베이스에 레코드를 삽입하는 경우 외래 키 열에 제품 테이블의 기본 키 값에 존재하는 값이 있는지 확인하려고합니다. Product Categories 테이블에 새 항목을 추가 할 때마다 데이터베이스에서 작업이 오버 헤드됩니다. 따라서 외래 키를 추가해도 데이터베이스 성능은 향상되지 않지만 데이터베이스의 무결성을 관리합니다. 그렇습니다. 프로그램의 데이터베이스에 레코드가 있는지 확인하기 위해 많은 쿼리를 실행하는 대신 외래 키를 사용하여 무결성을 검사하는 경우 db의 성능이 향상됩니다.