2011-04-24 5 views
1

'books'테이블이 있고, 기본 키가있는 여러 테이블과 값 : E.G 'library'및 'genre'가 있습니다. 그런 다음이 기본 키는 모든 책에 대한 'books'테이블에 저장됩니다.mysql 선택 캐시 최적화

도서관 A의 모든 도서를 검색하는 효율적인 방법은 무엇입니까?

어떤 접근 방법 :

  • 선택 내부 조인 및 분류 라이브러리 열을 사용하여 - 임시 테이블에 innefficient를? 빠른 속도로 데이터를 색인하는 영리한 방법?
  • 기본 키가 일치하지 않는 데이터베이스 대신 'books'테이블에 텍스트 값을 복사 하시겠습니까?
  • 하위 쿼리 select books where library = (select id where library = 'A') 사용 - mysql이 하위 쿼리를 캐시합니까?
  • 두 개의 쿼리를 보내고 라이브러리 A의 기본 ID를 PHP/memcached - messy 구현에 캐시 하시겠습니까?

왜 이렇게하는 것이 좋습니다?

답변

0

내가 갈 것이다 : 내부로

  • 단일 SQL 쿼리
  • 는이에 할 수있는 가장 논리적 인 일이의 books 모든 후 library

간의 조인 상황의 종류, 고려 :

  • 당신은 관계형 데이터 기본 시스템
  • 데이터가 올바르게 구조화 된 것처럼 보입니다.


당신이 최적화에, 그래, 당신이 당신의 마지막 점을 거의 사용할 수있는 일을하려는 경우; 하지만 확실하지 않은 그 많은 실제로 바꿀 것 :

  • 당신은 올바른 인덱스 를 사용하여 데이터베이스
  • 에 두 개의 쿼리를 보낼 것입니다 (당신은 아마, 외국인 키와 이노를 사용하는 경우), 하나 개의 쿼리가 작동합니다 꽤 빠릅니다.

캐시를 추가하려면 전체 서적 검색 결과를 캐싱해야합니다.

+0

외래 키를 사용하면 mysql이 임시 테이블을 만들 필요가 없으며 결과 집합을 정렬 할 필요가 없다는 뜻입니까? E.G 실제 정렬을 시작하기 전에 전체 책 결과 세트의 조인 된 값으로 임시 테이블을 올리십시오. –

2

라이브러리와 책 사이의 관계형 모델을 사용하고 조인을 사용하여 쿼리합니다. library_id에 대한 기본 키와 색인이 설정되어 있으면 상당히 빠릅니다.

table: libraries 
+-------+--------------+------+-----+---------+-------+ 
| Field | Type   | Null | Key | Default | Extra | 
+-------+--------------+------+-----+---------+-------+ 
| id | int(11)  | YES | PRI | NULL |  | 
| name | varchar(100) | NO |  | NULL |  | 
+-------+--------------+------+-----+---------+-------+ 
+------+------+ 
| id | name | 
+------+------+ 
| 1 | Foo | 
| 2 | Bar | 
+------+------+ 

table: books 
+------------+--------------+------+-----+---------+-------+ 
| Field  | Type   | Null | Key | Default | Extra | 
+------------+--------------+------+-----+---------+-------+ 
| id   | int(11)  | NO | PRI | 0  |  | 
| library_id | int(11)  | NO | MUL | NULL |  | 
| author  | varchar(100) | NO |  | NULL |  | 
| name  | varchar(100) | NO |  | NULL |  | 
+------------+--------------+------+-----+---------+-------+ 
+----+------------+--------+------+ 
| id | library_id | author | name | 
+----+------------+--------+------+ 
| 1 |   1 | Jon | Baz | 
| 2 |   1 | Bill | Baz | 
| 3 |   2 | Mary | Abc | 
+----+------------+--------+------+ 

이 매우 쉽게 쿼리 수 있습니다.'푸'의 이름으로 도서관에있는 모든 책을 찾으려면,이 같은 쿼리를 사용하십시오 : 이미 라이브러리 ID를 알고있는 경우

mysql> SELECT books.* FROM books 
    -> JOIN libraries ON libraries.id = books.library_id 
    -> AND libraries.name = 'Foo'; 
+----+------------+--------+------+ 
| id | library_id | author | name | 
+----+------------+--------+------+ 
| 1 |   1 | Jon | Baz | 
| 2 |   1 | Bill | Baz | 
+----+------------+--------+------+ 

을, 당신도 필요하지 않습니다 조인 :

mysql> SELECT * FROM books 
    -> WHERE library_id = 2; 
+----+------------+--------+------+ 
| id | library_id | author | name | 
+----+------------+--------+------+ 
| 3 |   2 | Mary | Abc | 
+----+------------+--------+------+ 
1

관계 데이터베이스 성능을 원한다면 외래 키를 사용해야합니다. 색인은 빠르지 만 FK는 다른 끝에있는 것을 '알고'있기 때문에 더 빠릅니다. 이후에 성능 문제가 계속 발생하면 먼저 DB 엔진이 요청을 처리하는 방법을 이해해야합니다. 책이 많고 도서관에서 도서관이 먼저 라이브러리를 선택하는지 확인하십시오. '도서 내부 결합 도서관'이 아니라 '도서관 내부 결합 도서'. 두 테이블의 데이터를 사용하지 않으면 하위 쿼리로 이동해야합니다. 그러면 엔진은 전체 테이블 대신 조인에 대한 하위 쿼리의 키만 사용합니다. (PHP) 코드를 사용하여 다음 쿼리에 대해 데이터베이스 결과를 캐시하지 마십시오. 일들이 복잡해지면 임시 테이블을 사용하십시오.