2011-03-14 4 views
0

아래와 같이 쿼리를 개선하려면 어떻게해야합니까?이 Zend_Search_Lucene 쿼리의 성능을 향상 시키려면 어떻게해야합니까?

키워드 필드 인 item_id를 제외하고 내 색인이 완전히 최적화되었으며 모든 필드가 저장되지 않습니다.

문제는 "if ($ auth) {"섹션에 있습니다. 이 섹션이 제거되면 검색 시간은 항상 1 초 미만이지만이 섹션을 검색 시간에 추가하면 5 초 이상입니다. 분명히 그것은 더 복잡한 질의이지만 그것 없이는 살 수는 없습니다. 사용자가 볼 수있는 검색 결과 만 얻으려면 해당 섹션의 논리가 필요합니다. 나는 "if ($ authQuery) {$ query-> addSubquery ($ authQuery, true);}"라는 줄을 제거하면 탐색 속도가 느려지는 것을 안다.

나는 "만약 ($의 인증) {"기본적으로 다음과 같은 논리를 초래하는 섹션을 시도하고있다 : 모든 단일 정수 각

에 지나지 구성

루씬 필드 gi_aro, gc_aro, i_access 및 c_access을

if ((array_in({gi_aro}, $gmid) OR {i_access} <= $gid) 
    AND (array_in({gc_aro}, $gmid) {OR c_access} <= $gid)) { 
    include in search results 
} 

{} = 루씬 필드 무엇을하지 인덱스 내부의 결과 만 확인에 대한

// keywords query 
$keywords = explode(' ', $keyword); 

$keywordQuery = new Zend_Search_Lucene_Search_Query_Multiterm(); 
foreach ($keywords as $term) { 
    $keywordQuery->addTerm(new Zend_Search_Lucene_Index_Term($term, 'content')); 
    $keywordQuery->addTerm(new Zend_Search_Lucene_Index_Term($term, 'search_display_name')); 
} 

// topcat query 
if (!empty($topcat)) { 
    $term = new Zend_Search_Lucene_Index_Term($topcat, 'topcats'); 
    $topcatQuery = new Zend_Search_Lucene_Search_Query_Term($term); 
} 

// cat query 
if (!empty($cat)) { 
    $term = new Zend_Search_Lucene_Index_Term($cat, 'cats'); 
    $catQuery = new Zend_Search_Lucene_Search_Query_Term($term); 
} 

// only authorized items query 
if ($auth) { 
    $user = JFactory::getUser(); 
    $gid = (int)$user->get('aid'); 
    $gmid = explode(',', $user->gmid); 

    // flexicontent cat auth 
    $gcQuery = new Zend_Search_Lucene_Search_Query_MultiTerm(); 
    foreach ($gmid as $g) { 
    $gcQuery->addTerm(new Zend_Search_Lucene_Index_Term($g, 'gc_aro')); 
    } 

    // stock joomla cat auth 
    $lowCAccessTerm = new Zend_Search_Lucene_Index_Term(0, 'c_access'); 
    $highCAccessTerm = new Zend_Search_Lucene_Index_Term($gid, 'c_access'); 
    $cAccessQuery = new Zend_Search_Lucene_Search_Query_Range($lowCAccessTerm, $highCAccessTerm, true); 

    // ORed flexicontent cat auth & stock joomla cat auth 
    $catAuthQuery = new Zend_Search_Lucene_Search_Query_Boolean(); 
    $catAuthQuery->addSubquery($gcQuery); 
    $catAuthQuery->addSubquery($cAccessQuery); 

    // flexicontent itm auth 
    $giQuery = new Zend_Search_Lucene_Search_Query_MultiTerm(); 
    foreach ($gmid as $g) { 
    $giQuery->addTerm(new Zend_Search_Lucene_Index_Term($g, 'gi_aro')); 
    } 

    // stock joomla itm auth 
    $lowIAccessTerm = new Zend_Search_Lucene_Index_Term(0, 'i_access'); 
    $highIAccessTerm = new Zend_Search_Lucene_Index_Term($gid, 'i_access'); 
    $iAccessQuery = new Zend_Search_Lucene_Search_Query_Range($lowIAccessTerm, $highIAccessTerm, true); 

    // ORed flexicontent itm auth & stock joomla itm auth 
    $itmAuthQuery = new Zend_Search_Lucene_Search_Query_Boolean(); 
    $itmAuthQuery->addSubquery($giQuery); 
    $itmAuthQuery->addSubquery($iAccessQuery); 

    // ANDed itmAuthQuery & catAuthQuery 
    $authQuery = new Zend_Search_Lucene_Search_Query_Boolean(); 
    $authQuery->addSubquery($catAuthQuery, true); 
    $authQuery->addSubquery($itmAuthQuery, true); 
} 

// composite query 
$query = new Zend_Search_Lucene_Search_Query_Boolean(); 
$query->addSubquery($keywordQuery, true); 
// if cat query is set we don't need topcat to restrict result set 
if ($catQuery) { 
    $query->addSubquery($catQuery, true); 
} elseif ($topcatQuery) { 
    $query->addSubquery($topcatQuery, true); 
} 
if ($authQuery) { $query->addSubquery($authQuery, true); } 

// search 
$execTime = new JProfiler(); 
$this->hits = $index->find($query); 
echo $execTime->mark('executed'); 

답변

0

? 인덱스에 일종의 키를 저장하십시오 (db 기본 키, guid, 실질적으로 모든 것). 그런 다음 결과를 가져 와서 사용자가 볼 수 없도록 제거하십시오.

$allowedArray = $acl->getAllowedIds(); 
// check happens when echoing the content to prevent double cycling (filtering and echoing in view) 
foreach ($result as $item) { 
    if (in_array($item->keyVaue, $allowedArray)) { 
     //echo 
    } 
} 

편집 : 참고 대부분의 쿼리의 결과에 따라 달라집니다. 정규 쿼리에서 < 결과가 나온다면 PHP로 처리하면됩니다. 그러나 10,000 개의 결과와 같은 일반적인 쿼리가 반환되면 좋은 생각이 아닐 수도 있습니다.)

+0

응답을 보내 주셔서 감사 드리지만 쿼리는 일반적으로 1000 개가 넘는 결과를 반환하며 모두 루핑하는 데 너무 많은 시간이 걸립니다. 이전에 그 일을하고 있었지만 루프가 너무 비싸서 결과 세트를 줄이고 표시 할 결과를 "만지기"시작했지만 검색 결과가 너무 느립니다. 나는 어떻게 생각 하느냐 그러나 당분간 받아 들일 수있게 달려있다. 너무 느려지면 솔로로 전환해야 할 것 같아요. – rushinge

+0

다른 옵션은 SQL에 대체 될 수 있습니다. :) –

관련 문제