2014-02-16 9 views
1

재귀 with 문을 사용하여 트리 구조 항목을 나타내는 테이블의 주어진 부모로부터 모든 자식을 선택하고 있습니다. 이것은 Sqlite에 있습니다 (이제 재귀 적으로 지원됩니다).
이렇게하면 호출 응용 프로그램에서 수천 개의 select 문을 준비하기 때문에 엄청난 성능 손실을 겪지 않고이 트리에서 매우 빠르게 수천 개의 레코드를 선택할 수 있습니다.Sqlite에서 다음 쿼리의 SQL 쿼리 결과 재사용

WITH RECURSIVE q(Id) AS 
(
    SELECT Id FROM Entity 
    WHERE Parent=(?) 
    UNION ALL 
    SELECT m.Id FROM Entity AS m 
    JOIN Entity ON m.Id=q.Parent 
) 
SELECT Id FROM q; 

지금, 나는 이후에로드 할 것을, 나는 다른 테이블의 임의의 수에 이들 엔티티에 데이터를 관련했다고 가정합니다. 이들 중 임의의 숫자 (모듈 식 방식으로) 때문에이 데이터 가져 오기를이 모듈에 직접 포함시킬 수 없습니다. 그들은 그것을 따라야 만합니다.

그러나 각각의 관련 테이블에 대해 SELECT 문을 수행하면 Sqlite에서 직접 트리의 모든 데이터를 선택하여 얻는 모든 성능 향상은 거의 쓸모가 없습니다. select 문을 발행하십시오.

그래서 두 가지 질문 :

  1. 더 나은 솔루션을 반복적으로 다시이 나무에서 개체를 수집하는 것, 관련 각 테이블에 대한 유사한 재귀 문을 공식화하는 것입니다,이 시간은 자신의 관련 데이터를 선택 그것에 합류함으로써. 이것은 실제로 더 효율적이라고 들리지만, 그러한 진술을 공식화하는 것은 매우 까다 롭습니다.

  2. 이제 실제 수수께끼는 어딘가에 캐시 된 마지막 쿼리 (엔티티 트리의 ID가있는 행)에서 이러한 결과를 유지하는 것이 더 효율적인 솔루션이 될 것입니다. 재귀 적으로 다시 반복 할 필요없이 다음 문에서 관련 테이블을 다시로드 할 수 있습니까?

필드를 선택하려고 할 때 첫 번째 옵션을 시도해보십시오. 관련 테이블에서 데이터 구성 요소 : 두 번째 UNION 모두 합법입니까?

WITH RECURSIVE q(Data) AS 
(
    SELECT Id FROM Entity 
    WHERE Parent=(?) 
    UNION ALL 
    SELECT m.Id FROM Entity AS m 
    JOIN Entity ON m.Id=q.Parent 
    UNION ALL 
    SELECT Data FROM Component AS c 
    JOIN Component ON c.Id=q.Id 
) 
SELECT Data FROM q; 

답변

1

documentation는 말한다 :

2. 화합물의 가장 오른쪽 SELECT 문의 FROM 절 정확히 한 번에 표시해야 AS 키워드의 왼쪽에 이름이 표 선택하고 다른 곳에서는 없습니다.

두 번째 쿼리는 유효하지 않습니다.

WITH RECURSIVE q(Id) AS 
(...) 
SELECT q.Id, c.Data 
FROM q JOIN Component AS c ON q.Id = c.Id 

여러 쿼리 q에서 계산 된 값을 다시 사용하려는 경우, 아무것도 :

그러나 CTE는 방금 관련된 테이블에 가입 할 수 있도록, 일반 테이블/뷰처럼 동작 CTE로 할 수는 있지만 임시 테이블에 저장할 수 있습니다.

CREATE TEMPORARY TABLE q_123 AS 
WITH RECURSIVE q(Id) AS 
(...) 
SELECT Id FROM q; 

SELECT * FROM q_123 JOIN Component ...; 
SELECT * FROM q_123 JOIN Whatever ...; 

DROP TABLE q_123; 
+0

Nice! 임시 테이블을 만드는 이러한 사용 사례 (레코드 10,000 개)가 첫 번째 옵션보다 더 재미있을 것이라고 생각합니까? 나는이 해결책을 시도하고 당신 등을 맞댄 얻을 것이다. – MONK