2015-11-25 3 views
1

Некоторые операторы SELECT занимают несколько секунд, чтобы вернуть данные, и я хотел бы узнать, могу ли я улучшить производительность. БД обычно довольно мала (~ 10-40 МБ), но чем больше она получается, тем дольше она требуется. Один примера запрос, который занимает очень долгое время является следующим:Как улучшить производительность SELECT SELECT?

SELECT intf_id FROM interfaces 
WHERE intfType IN (SELECT intfType FROM interfaces 
WHERE intf_id=39151) 
AND macAddress IN (SELECT l2_addr FROM neighbor 
INNER JOIN nlink ON nlink.neighbor_neighbor_id=neighbor.neighbor_id 
INNER JOIN interfaces ON interfaces.intf_id=nlink.interfaces_intf_id 
WHERE interfaces.intf_id=39151) 
AND status LIKE 'UP' AND phl=1 AND intf_id <> 39151 

Может быть, это из-за вложенным ЗЕЬЕСТ?

БД Макет выглядит следующим образом: DB Layout

EXPLAIN QUERY PLAN Выход: enter image description here

EXPLAIN QUERY PLAN CSV:

"0","0","0","SCAN TABLE interfaces USING COVERING INDEX ii1" 
"0","0","0","EXECUTE LIST SUBQUERY 1" 
"1","0","0","SEARCH TABLE interfaces USING INTEGER PRIMARY KEY (rowid=?)" 
"0","0","0","EXECUTE LIST SUBQUERY 2" 
"2","0","2","SEARCH TABLE interfaces USING INTEGER PRIMARY KEY (rowid=?)" 
"2","1","0","SCAN TABLE neighbor" 
"2","2","1","SEARCH TABLE nlink USING COVERING INDEX sqlite_autoindex_nlink_1 (neighbor_neighbor_id=? AND interfaces_intf_id=?)" 
+3

Этот вопрос довольно широк, чтобы дать определенный ответ. Вы можете начать с запуска 'EXPLAIN QUERY PLAN' и посмотреть, что на самом деле делает запрос. Если слишком много сканирований таблиц, вы, вероятно, захотите создать индексы, чтобы ускорить их. См. Https://www.sqlite.org/eqp.html для получения более подробной информации о 'EXPLAIN QUERY PLAN'. – Munir

+0

Редактировать вопрос, чтобы показать результат 'EXPLAIN QUERY PLAN' для этого запроса. Или еще лучше, также создайте минимальную [скрипт SQL] (http://sqlfiddle.com/#!5), чтобы другие могли протестировать запрос. –

+0

Благодарим вас за подсказку. Я добавил вывод к вопросу. Есть ли какие-либо варианты, или выход нормально? – mspoerr

ответ

2

вы могли бы попытаться создать индекс на interfaces.macAddress и вместо этого используется следующий объединенный запрос? В этом случае подзапросы выглядят медленнее.

SELECT interface_RH.intf_id FROM interfaces AS interface_LH 
      INNER JOIN nlink ON nlink.interfaces_intf_id = interface_LH.intf_id 
      INNER JOIN neighbor ON nlink.neighbor_neighbor_id = neighbor.neighbor_id 
      INNER JOIN interfaces AS interface_RH ON interface_RH.macAddress = neighbor.l2_addr 
WHERE 
      interface_LH.intf_id=39151 
      AND interface_RH.status LIKE 'UP' 
      AND interface_RH.phl = 1 
      AND interface_RH.intf_id <> 39151 
      AND interface_RH.intfType = interface_LH.intfType 
Смежные вопросы