2013-11-01 2 views
0

내 MySQL의 DB의 단순화 된 버전은 다음과 같습니다인덱스를 사용하지 않고 MySQL 쿼리를 최적화 할 수 있습니까?

Table books (ENGINE=MyISAM) 
id <- KEY 
publisher <- LONGTEXT 
publisher_id <- INT <- This is a new field that is currently null for all records 

Table publishers (ENGINE=MyISAM) 
id <- KEY 
name <- LONGTEXT 

현재의 books.publisher 반복 점점 계속 값을 보유하고 있지만, publishers.name는 유일하게 보유하고있다. books.publisher를 없애고 대신 books.publisher_id 필드를 채우고 싶습니다.

UPDATE books 
JOIN publishers ON books.publisher = publishers.name 
SET books.publisher_id = publishers.id; 

문제는 내가 기록의 큰 숫자를 가지고 있고, 작동하더라도, 그것은 영원히 복용한다는 것입니다 다음과 같이

내가 완료 원하는 것을 설명하는 간단한 SQL 코드이다.

CREATE INDEX publisher ON books (publisher(20)); 
+2

조금 혼란 스럽습니다. 나는 너를하려고 생각했다. SET books.publisher_id = publishers.id; 아니? –

+1

"많은 수의 기록을 명확히 할 수 있습니까?" 어떤 액세스 방법 (InnoDB? MyISAM?)을 사용하고 있습니까? "영원히"라는 말은 아직 완성되지 않았다는 것을 의미한다고 생각합니다. 이런 종류의 물건에는 오랜 시간이 걸립니다. 이러한 일회성 데이터 재구성은 완료하는 데 여러 시간이 걸릴 수 있으며 때로는 야간 또는 일부 실행해야 할 때도 있습니다. –

+0

이것은 [tag : php]와 아무런 관련이 없습니다. – geomagas

답변

1

최적화에 도움이 될 수있는 몇 가지 문제가 있습니다.

우선, 수천 개의 행은 "큰"것으로 계산되지 않습니다 ... "중간"입니다.

둘째로, "인덱스없이 이것을하고 싶다"는 말은 "나는 뉴욕시에 내 차를 운전하고 싶다. 그러나 내 타이어는 평평하고 나는 그것들을 펌프질하고 싶지 않다. 뉴욕으로가는 가장 좋은 길은 내가 바퀴 달린 거리라면? "

셋째로 게시자에 LONGTEXT 항목을 사용하고 있습니다. VARCHAR(200)과 같이 완전 인덱싱 가능 데이터 유형을 사용하지 않는 이유가 있습니까? 그렇게하면 WHERE 문이 더 빨리 실행되거나 색인 또는 없음이 실행됩니다. 대규모 라이브러리 카탈로그 시스템은 게시자 필드의 길이를 제한하므로 시스템도 사용할 수 있습니다.

넷째, 귀하의 의견 중 하나를 보면 일회성 데이터 유지 관리 업데이트처럼 보입니다. 따라서 전체 거래를 반복해서 반복하지 않는 방법을 알아야합니다. 여기서 추측하고 있지만 새로 삽입 된 행의 books 테이블에 publisher_id가 0으로 표시되고 쿼리에서 해당 값을 유효한 값으로 업데이트합니다.

그래서해야 할 일이 있습니다. 먼저, tables.publisher_id에 색인을 붙이십시오.

둘째, 유지 보수 쿼리의 변형을 실행

UPDATE books 
    JOIN publishers ON books.publisher = publishers.name 
    SET books.publisher_id = publishers.id 
WHERE books.publisher_id = 0 
LIMIT 100; 

이 아직 업데이트되지 않은 행에 업데이 트를 제한합니다. 또한 한 번에 100 개의 행을 업데이트합니다. 매주 데이터 유지 관리 작업에서 MySQL이 쿼리가 제로 행에 영향을 준다는 것을 알릴 때까지이 쿼리를 다시 발행하십시오 (mysqli :: rows_affected 또는 php-mysql 인터페이스의 해당 항목 참조). 이는 데이터베이스 업데이트 진행 상황을 모니터링하고 업데이트 작업이 중단되는 것을 막을 수있는 좋은 방법입니다.

-1

귀하의 업데이트 쿼리가 잘못된 구문이 있지만 나중에 고칠 수? 사전에 이런 식으로 뭔가를 사용하는 것보다 더 빠른 해결책이 있습니다. 이를 빠르게 실행하는 방법은 where 절을 추가하여 필요한 레코드 만 업데이트하는 것입니다.

+1

WHERE 절이 도움이되지 않는다고 생각합니다. 테이블에 추가 된 새 필드를 업데이트하고 있으므로 _ALL_ 행이 변경됩니다. – Tony

+0

공정하게하려면 WHERE 절을 추가하면 후속 업데이트의 속도가 빨라집니다. – Tony

+0

이후의 업데이트는 내가 염두에 두었던 것입니다. 첫 번째 작업에 오랜 시간이 걸리면 한 번만 수행하면되므로 큰 문제는 아닙니다. –

2

당신의 질문 제목은 ".. 색인을 사용하지 않고 쿼리를 최적화합니까?"라고 말합니다.

색인을 사용하여 얻은 이점은 무엇입니까?

쿼리가 느리게 실행되는 경우 항상 실행 계획을 검사해야합니다. 일치하는 항목을 찾으려면 각 행의 publishers 테이블을 스캔해야합니다. id의 검색 속도를 높이려면 publishers.name에 대한 색인이 있어야합니다.

인덱스를 나중에 삭제할 수 있지만 다른 변경 사항이있을 때까지 프로세스를 잠시 실행해야한다고 말하기 때문에 색인을 남겨 두어도 해가되지는 않습니다. publishers 테이블이 매우 자주 업데이트되지 않으므로 테이블에있는 INSERTUPDATE의 성능이 문제가되지 않아야합니다.

관련 문제