2009-05-20 3 views
0

Я использую следующий запрос, чтобы выяснить, к началу 6 просмотренных страниц на моем сайте Drupal:Как оптимизировать следующий запрос

SELECT n.title, n.nid, c.daycount 
FROM node n 
JOIN node_counter c ON n.nid=c.nid 
WHERE n.type='page' AND n.status = 1 
ORDER BY c.daycount DESC 
LIMIT 0,6; 

Это очень естественно и хорошо работает на большинстве сайтов. Однако на сайте со многими узлами (1,7 м) он выходит довольно медленно, и он вряд ли кэшируется, поскольку таблица узлов продолжает меняться, поскольку пользователи добавляют/редактируют узлы в системе.

Запуск объяснить на тяжелом участке производит следующий вывод:

+----+-------------+-------+--------+-----------------------------------------------+------------------+---------+------------------+-------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys         | key    | key_len | ref    | rows | Extra          | 
+----+-------------+-------+--------+-----------------------------------------------+------------------+---------+------------------+-------+----------------------------------------------+ 
| 1 | SIMPLE  | n  | ref | PRIMARY,node_type,status,node_status_type,nid | node_status_type | 102  | const,const  | 71878 | Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | c  | eq_ref | PRIMARY          | PRIMARY   | 4  | kidstvprd2.n.nid |  1 | Using where         | 
+----+-------------+-------+--------+-----------------------------------------------+------------------+---------+------------------+-------+----------------------------------------------+ 

Обратите внимание на «Использование где, используя временный, используя FileSort».

Одно из решений, о которых я думал, запускает этот запрос в автономном режиме (возможно, в cron) и сохраняет результаты в другой таблице для тех, кто читает их, до тех пор, пока следующий запуск cron не обновит его. Однако, прежде чем возвращаться в cron, я хотел бы попытаться оптимизировать этот запрос.

Есть ли у кого-нибудь идеи о том, как его оптимизировать?

Благодаря

ответ

2

Проблема заключается в том, что он, начиная с п таблицы, а не с. Вы хотите использовать индекс на c.daycount (во избежание сортировки), а затем присоединить его к n. Если необходимо, используйте straight_join для принудительного выполнения заказа.

Смотрите также http://dev.mysql.com/doc/refman/5.1/en/join.html

+0

Удивительно! это работало очень хорошо. Я не знал о том, как прямолинейно и стыдно. Я просто предположил, что mySQL делает лучшее для меня ... – yhager

0

В SQLServer я бы обязательно иметь следующие показатели

CREATE INDEX IX_NODE_NID_TYPE_STATUS_TITLE 
    ON dbo.Node (Nid, Type, Status) INCLUDE (Title) 

CREATE INDEX IX_NODE_COUNTER_NID_DAYCOUNT 
    ON dbo.Node_Counter (Nid, DayCount) 
Смежные вопросы