camka
не самка
возможно ли оптимизировать подобный запрос?
Выбираю TOP самых искомых слов за заданный период времени (id between xxx and xxx) для определенного поисковика(ов) (engine in (x,xx,xxx)).
Таблица слов
-----------------
id - уник. идентификатор слова (первичный ключ)
k - само искомое слово/фраза (уникальный индекс)
Таблица статистики
--------------------------
id - дата(день) (индексировано, является первой частью составного индекса)
hits - количество раз, сколько искали фразу
query - ссылка на слово(id) в таблице слов (индексировано)
engine - идентификатор поисковика
и еще индекс для (engine, id)
[sql]
select r.k as word, sum(s.hits) as hits from words r inner join stats s on r.id = s.query where s.engine in (3) and s.id between 20041101 and 20041207 group by r.id order by hits desc, r.k limit 100 ;
[/sql]
table words - 200 000 zapisej
table stats - 300 000 zapisej
EXPLAIN
Проблема в том, что если, как показано в запросе, период слишком большой, составной индекс engine_id используется не полностью, что понятно. Но скорость запроса значительно замедляется, что неприемлемо.
Возможно ли как то оптимизировать этот запрос???
Для сравнения привожу запрос с меньшим временным периодом.
[sql]
select r.k as word, sum(s.hits) as hits from words r inner join stats s on r.id = s.query where s.engine in(3) and s.id between 20041201 and 20041207 group by r.id order by hits desc, r.k limit 100 ;
[/sql]
Может быть существуют стандартные решения, как избавиться от Using temporary; Using filesort ???
спасибо.
Выбираю TOP самых искомых слов за заданный период времени (id between xxx and xxx) для определенного поисковика(ов) (engine in (x,xx,xxx)).
Таблица слов
-----------------
id - уник. идентификатор слова (первичный ключ)
k - само искомое слово/фраза (уникальный индекс)
Таблица статистики
--------------------------
id - дата(день) (индексировано, является первой частью составного индекса)
hits - количество раз, сколько искали фразу
query - ссылка на слово(id) в таблице слов (индексировано)
engine - идентификатор поисковика
и еще индекс для (engine, id)
[sql]
select r.k as word, sum(s.hits) as hits from words r inner join stats s on r.id = s.query where s.engine in (3) and s.id between 20041101 and 20041207 group by r.id order by hits desc, r.k limit 100 ;
[/sql]
Код:
+--------------------------+------+
100 rows in set (5 min 22.58 sec)
table stats - 300 000 zapisej
EXPLAIN
Код:
+-------+--------+--------------------+-----------+---------+---------+--------+----------------------------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+--------+--------------------+-----------+---------+---------+--------+----------------------------------------------+
| s | ref | id,query,engine_id | engine_id | 4 | const | 153874 | Using where; Using temporary; Using filesort |
| r | eq_ref | PRIMARY | PRIMARY | 4 | s.query | 1 | |
+-------+--------+--------------------+-----------+---------+---------+--------+----------------------------------------------+
Возможно ли как то оптимизировать этот запрос???
Для сравнения привожу запрос с меньшим временным периодом.
[sql]
select r.k as word, sum(s.hits) as hits from words r inner join stats s on r.id = s.query where s.engine in(3) and s.id between 20041201 and 20041207 group by r.id order by hits desc, r.k limit 100 ;
[/sql]
Код:
+-------+--------+--------------------+-----------+---------+---------+-------+----------------------------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+-------+--------+--------------------+-----------+---------+---------+-------+----------------------------------------------+
| s | range | id,query,engine_id | engine_id | 8 | NULL | 15976 | Using where; Using temporary; Using filesort |
| r | eq_ref | PRIMARY | PRIMARY | 4 | s.query | 1 | |
+-------+--------+--------------------+-----------+---------+---------+-------+----------------------------------------------+
2 rows in set (0.03 sec)
спасибо.