데이터베이스 엔진 (즉, SQL의 종류)에 따라 다르지만 거의 각 SQL 플레이버는 페이지 매김을 지원합니다 쿼리.
예를 들어, MySQL은 LIMIT이고 MS SQL은 ROW_NUMBER입니다.
평소와 같이 SQL을 빌드 한 다음 데이터베이스 엔진 별 페이지 매김을 추가하면 서버는 쿼리 결과의 행 10에서 20까지를 자동으로 반환합니다.
는
편집 : 나는 예상대로
그래서 (사용자에게 반환되는 데이터를 선택) 최종 쿼리는 일부 테이블 (임시되지 않음)에서 데이터를 선택합니다.
쿼리입니다.이 쿼리는 MySQL에서 LIMIT
으로 페이지 할 수 있습니다.
실제 계산이 사용자에게 결과를 반환하는 최종 쿼리보다 리소스를 더 많이 소모하는 것처럼 사용자의 설명이 내게 들립니다.
그래서 나는 다음을 수행합니다 :
- 입력 한 단어에 대한 개별 결과 테이블을 얻을, 예를 들면 (나중에이 명시한다 쿼리에 대한 데이터를 얻을 수있는 방법으로 테이블에 저장 , SessionID 또는 QueryID와 같은 추가 열이 있음). 여기서 페이지 매김을하지 않습니다.
- 은 사용자에게 반환되는 최종 쿼리에 대해 이러한 결과 테이블을 다시 쿼리합니다.
여기서 LIMIT
을 사용하여 페이징을 수행 할 수 있습니다.
사용자가 쿼리를 "시작할"때 실제 계산 (리소스 호깅 쿼리)을 한 번만 수행해야합니다.그런 다음 이미 채워진 결과 표에서 선택하여 페이지가 매겨진 결과를 사용자에게 반환 할 수 있습니다.
편집 2 :
난 그냥 당신이 내 대답을 받아 보았다,하지만 여전히, 여기에 "임시"테이블 내 사용에 대한 자세한 내용은입니다.
물론 이것은 가능한 한 가지 방법 일뿐입니다. 예상 결과가 너무 크지 않은 경우 전체 결과 집합을 클라이언트에 반환하고 메모리에 유지하고 페이징 클라이언트 쪽을 수행하는 것이 좋습니다.
그러나 사용자가 몇 가지 (Google 검색 결과를 생각할 수 있음) 및/또는 대역폭이 낮은 엄청난 양의 데이터에 대해서는 가능한 한 적은 데이터 만 클라이언트로 전송하려고합니다.
내가이 대답을 쓸 때 생각했던 것입니다.
So : "실제"임시 테이블을 의미하지는 않습니다. 임시 데이터를 저장하는 데 사용되는 "정상적인"테이블을 말합니다.
나는 MS SQL보다 MySQL에 익숙하기 때문에 MySQL의 임시 테이블에 대해 많이 알지 못합니다.
나는 MS SQL에서 어떻게 할 것인지 알려주지 만, 아마도 모르는 MySQL에서 이것을 할 수있는 더 좋은 방법이있을 것입니다.
리소스 집약적 인 쿼리를 처리해야 할 때 실제 계산을 한 번 수행하고 테이블에 저장 한 다음 해당 테이블을 클라이언트에서 여러 번 쿼리해야합니다 (각 페이지에 대해 계산을 다시하지 않으려면).
문제는 : MS SQL에서 임시 테이블은 쿼리가 생성 된 쿼리의 범위에만 존재합니다.
두 번째 쿼리를 수행 할 때 임시 테이블을 사용할 수 없으므로 임시 테이블을 사용할 수 없습니다.
그래서 "진짜"테이블을 사용합니다.
올바른 알고리즘인지 아닌지 잘 모르겠습니다. 따라서 예제를 약간 간소화 할 것입니다.
이 테이블 (이이 개념을 보여주기 위해 그냥, 아마도 유효하지 않습니다 MySQL을 것입니다) 일 : 나는 어쨌든 내 지점을 명확하게 할 수 있기를 바랍니다
create table AlgorithmTempTable
(
QueryID guid,
Rank float,
Value float
)
내가 전에 말했듯이 - 그것은 문자 그대로 아니다 "임시"테이블은 실제로 임시 데이터로 사용되는 실제 영구 테이블입니다.
사용자가 응용 프로그램을 열고 검색 단어를 입력 한 다음 "검색"버튼을 누릅니다.
그럼 당신은 한 번 결과를 계산하기 위해 자원 무거운 알고리즘을 시작하고 테이블에 저장 :
insert into AlgorithmTempTable (QueryID, Rank, Value)
select '12345678-9012-3456789', foo, bar
from Whatever
insert into AlgorithmTempTable (QueryID, Rank, Value)
select '12345678-9012-3456789', foo2, bar2
from SomewhereElse
의 GUID는 클라이언트에 알려 져야한다. 어쩌면 당신은 클라이언트의 SessionID를 사용할 수 있습니다 (만약 그가 하나의 쿼리를 가지고 있고 한번에 두 개 이상의 쿼리를 시작할 수 없다면 ... 또는 사용자가 "검색"버튼을 누를 때마다 클라이언트에 새로운 Guid를 생성합니다) 또는 무엇이든).
이제 모든 계산이 완료되고 순위가 매겨진 결과 목록이 표에 저장됩니다.
은 이제를 QueryID에 의해 필터링 테이블을 조회 할 수 있기 때문에를 QueryID의
select Rank, Value
from AlgorithmTempTable
where QueryID = '12345678-9012-3456789'
order by Rank
limit 0, 10
는 여러 사용자가 동시에 수행 할 수 있습니다 서로의 쿼리를 방해하지 않고. 각 검색에 대해 새 QueryID를 작성하면 동일한 사용자가 여러 쿼리를 한 번에 실행할 수도 있습니다.
이제는 할 일이 하나 남았습니다. 더 이상 필요하지 않을 때 임시 데이터를 삭제하십시오 (데이터 만 삭제됨! 테이블이 삭제되지 않음).
따라서, 사용자는 쿼리 화면을 닫으면 :
delete
from AlgorithmTempTable
where QueryID = '12345678-9012-3456789'
이 있지만, 어떤 경우에는 적합하지 않습니다. 응용 프로그램이 충돌하면 데이터가 테이블에 영원히 남습니다.
몇 가지 더 좋은 방법이 있습니다. 어느 것이 당신에게 가장 적합한지는 당신의 신청에 달려 있습니다. 일부 가능성 : 당신은하지만, 대신의 기본 값으로 현재 시간과 날짜 시간 열을 추가 한 다음 상기와
같은 X에 비해 모든 나이가 삭제 야간 (또는 주간) 작업을 실행할 수 있습니다
- 주간 작업 누군가가 새 쿼리를 시작할 때마다 X보다 오래된 모든 것을 삭제할 수 있습니다.
- 사용자 당 세션이있는 경우 테이블의 추가 열에 SessionID를 저장할 수 있습니다. 사용자가 로그 아웃하거나 세션이 만료되면 테이블의 해당 SessionID를 가진 모든 것을 삭제할 수 있습니다.
이 정보가 도움이 될 수 있습니다. 질문은 다르지만 포함 된 쿼리가 아이디어를 줄 수 있습니다. http://stackoverflow.com/questions/9258955/return-two-result-sets-when-using-with-tempresults-as –