2014-09-02 2 views
1

Я не могу принять решение об индексировании. Как я есть ниже запрос, который занимает слишком много времени для выполнения:SQLite Индексирование

select count(rn.NODE_ID) as Count, 
     rnl.[ISO_COUNTRY_CODE] as Country, 
     rnl.[FUNCTIONAL_CLASS] as Functional_Class 
from RDF_NODE as rn, 
    RDF_LINK as rl, 
    RDF_NAV_LINK as rnl 
where rl.[LINK_ID] = rnl.[LINK_ID] 
    AND rn.NODE_ID IN (rl.[NONREF_NODE_ID], rl.[REF_NODE_ID]) 
GROUP BY rnl.[ISO_COUNTRY_CODE], 
     rnl.[FUNCTIONAL_CLASS] 

В то время как я использую EXPLAIN QUERY PLAN:

 
0 0 0 SCAN TABLE RDF_NODE AS rn USING COVERING INDEX NODE (~1000000 rows) 
0 1 2 SCAN TABLE RDF_NAV_LINK AS rnl (~6645278 rows) 
0 2 1 SEARCH TABLE RDF_LINK AS rl USING INDEX sqlite_autoindex_RDF_LINK_1 (LINK_ID=?) (~1 rows) 
0 0 0 EXECUTE LIST SUBQUERY 1 
0 0 0 USE TEMP B-TREE FOR GROUP BY 

Все таблицы, имеющей индексирование.

В чем разница между SCAN и SEARCH? Мы можем изменить заказ?

+0

Каковы индексы? –

+0

'SCAN' - это операция, в которой все строки должны быть повторены. ' ПОИСК 'похоже на то, что называется 'SEEK' на SQL Server, где возможно правильное использование индекса, и не все строки должны быть итерации, чтобы найти правильный – DrCopyPaste

+0

И это имеет смысл, потому что это «из RDF_NODE как rn, RDF_LINK как rl, RDF_NAV_LINK как rnl' является перекрестным соединением, и он имеет смысл перебирать все строки в этих таблицах, чтобы пересечь их, но, возможно,« INNER JOIN 'будет удовлетворять ваши потребности более эффективно. – DrCopyPaste

ответ

1

SCAN проходит через все строки таблицы (в том порядке, в котором они хранятся в таблице, обычно нет порядка), а ПОИСК ищет отдельные строки из таблицы.

SQLite реализует все объединения как объединения вложенных циклов. Самая внешняя таблица всегда доступна через SCAN (за исключением случаев, когда есть предложение WHERE, которое ограничивает возвращаемые строки). Все остальные таблицы должны быть доступны с помощью ПОИСК для поиска соответствующих записей; другой SCAN указывает, что нет индекса, который может использоваться для ускорения поиска, поэтому поиск каждого соответствия требует поиска всей таблицы.


Для этого конкретного запроса большое замедление является временной таблицей, используемой для реализации GROUP BY. Если все группировки столбцов в один индекс, это не является необходимым:

CREATE INDEX UseABetterIndexNameHere 
    ON RDF_NAV_LINK(ISO_COUNTRY_CODE, FUNCTIONAL_CLASS); 

(соединение между RDF_NAV_LINK и RDF_LINK требует RDF_LINK строк ищутся по их LINK_ID, поэтому этот столбец необходим индекс . Аналогично, RDF_NODE нуждается в индексе на NODE_ID. Но эти индексы уже существуют.)

Смежные вопросы