简体   繁体   English

您如何优化以下查询

[英]How would you optimize the following query

I am using the following query to find out to top 6 viewed pages in my Drupal site: 我正在使用以下查询来查找我的Drupal网站中排名前6的页面:

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;

This is very natural and works well on most sites. 这是非常自然的,并且在大多数站点上都可以正常工作。 However, on a site with many nodes (1.7m), it comes out rather slow, and it is hardly cached, since the node table keeps changing, as users add/edit nodes in the system. 但是,在具有许多节点(1.7m)的站点上,它的运行速度很慢,并且几乎不被缓存,因为随着用户在系统中添加/编辑节点,节点表不断变化。

Running explain on the heavy site produces the following output: 在繁重的站点上运行解释会产生以下输出:

+----+-------------+-------+--------+-----------------------------------------------+------------------+---------+------------------+-------+----------------------------------------------+
| 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                                  |
+----+-------------+-------+--------+-----------------------------------------------+------------------+---------+------------------+-------+----------------------------------------------+

Note the "Using where; Using temporary; Using filesort". 请注意“使用位置;使用临时;使用文件排序”。

One solution I thought about is running this query offline (in cron perhaps), and saving the results in another table for anyone to read from, until the next cron run updates it. 我想到的一个解决方案是离线运行此查询(也许在cron中),并将结果保存在另一个表中,以供任何人读取,直到下一次cron运行对其进行更新。 However, before reverting into cron, I'd like to try to optimize this query. 但是,在恢复为cron之前,我想尝试优化此查询。

Does anybody have an idea on how to optimize it? 有人对如何优化它有想法吗?

Thanks 谢谢

The problem is that it's starting with the n table rather than the c. 问题是它是从n表而不是c开始的。 What you want is for it to use an index on c.daycount (in order to avoid the sort), and then join that to n. 您想要的是使用c.daycount上的索引(以避免排序),然后将其连接到n。 If necessary, use straight_join to force the order. 如有必要,请使用straight_join强制执行该顺序。

See also http://dev.mysql.com/doc/refman/5.1/en/join.html 另请参见http://dev.mysql.com/doc/refman/5.1/en/join.html

In SQLServer I would make sure to have following indexes 在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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM