Как бы вы оптимизировали следующий запрос - PullRequest
0 голосов
/ 20 мая 2009

Я использую следующий запрос, чтобы узнать 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                                  |
+----+-------------+-------+--------+-----------------------------------------------+------------------+---------+------------------+-------+----------------------------------------------+

Обратите внимание на «Использование где; Использование временного; Использование сортировки файлов».

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

У кого-нибудь есть идеи по его оптимизации?

Спасибо

Ответы [ 2 ]

2 голосов
/ 20 мая 2009

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

См. Также http://dev.mysql.com/doc/refman/5.1/en/join.html

0 голосов
/ 20 мая 2009

В 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...