[텍스트큐브] 세션 gc 함수 SELECT DISTINCT → GROUP BY (임시 테이블 쓰지 않게 하기)
텍스트큐브/기워쓰기
2022/05/05 20:48
텍스트큐브의 세션(session) gc 함수(쓰레기 수집 함수, Garbage Collector)에는 Sessions 테이블에서 지워진 세션 정보를 SessionVisits에서도 지우려고 SessionVisits에서 지울 세션 목록을 만드는 SQL 구문이 있다. (/framework/legacy/Textcube.Control.Session.php)
$result = self::query('all',"SELECT DISTINCT v.id, v.address
FROM ".self::$context->getProperty('database.prefix')."SessionVisits v
LEFT JOIN ".self::$context->getProperty('database.prefix')."Sessions s ON v.id = s.id AND v.address = s.address
WHERE s.id IS NULL AND s.address IS NULL");
여기에 쓰인 DISTINCT 때문에 임시 테이블이 쓰이는데, DISTINCT를 쓰지 않고 GROUP BY를 쓰면 임시 테이블을 쓰지 않을 수 있다.
$result = self::query('all',"SELECT v.id, v.address
FROM ".self::$context->getProperty('database.prefix')."SessionVisits v
LEFT JOIN ".self::$context->getProperty('database.prefix')."Sessions s ON v.id = s.id AND v.address = s.address
WHERE s.id IS NULL AND s.address IS NULL GROUP BY v.id, v.address");
SQL 명령행에서 explain으로 보면, DISTINCT를 쓰면 'Using temporary'가 뜨지만, GROUP BY를 쓰면 'Using temporary'가 뜨지 않는다.
GROUP BY를 쓰면 차례짓기 작업 때문에 'Using filesort'가 뜨는 때도 있어서 DISTINCT를 쓰는 때보다 오히려 더 느릴 수도 있다고 한다. 하지만 이 경우에는 SessionVisits 테이블의 id와 address가 으뜸 열쇠값(PRIMARY KEY)이어서 차례짓기가 이미 되어 있으므로, GROUP BY를 쓰면 임시 테이블이 쓰이지 않고 차례짓기 작업도 따로 하지 않으면서 DISTINCT를 쓰는 때와 같은 결과를 얻을 수 있다.
덧글을 달아 주세요