【问题标题】:MySQL query to join 2 tables based on votesMySQL 查询基于投票连接 2 个表
【发布时间】:2014-03-15 05:40:54
【问题描述】:

我有一个 Web 应用程序,其中使用 2 个表,一个用于存储产品信息,另一个用于存储每个产品的投票。

现在我想根据产品获得的票数来展示产品。下面是表结构

产品:

PRODUCT_ID  TITLE
1           product1
2           product2
3           product3
4           product4

投票:

PRODUCT_ID  USER_ID
1           1
1           1
2           2
3           2

我期待结果以投票的降序显示产品

PRODUCT_ID  TITLE           VOTES
1           product1        2
2           product2        1
3           product3        1

目前我正在使用这样的查询

SELECT p.product_id, p.title, count(*) AS total FROM products p 
INNER JOIN votes v ON v.product_id = p.product_id  GROUP BY p.product_id 
ORDER BY count(*) DESC LIMIT 110

Products 表有大约 30,000 条记录,而 votes 表有大约 90,000 条记录。

现在的问题是它需要很多时间(随机在 18 到 30 秒之间)。由于表中的记录数量并不多,我想知道为什么要花这么多时间。

注意到的一件事是,当我第二次运行查询时,它会在几毫秒内获取结果,我认为这是处理这种不那么复杂的查询的理想时间。

我对编程的数据库方面还是很陌生。

我不确定查询中是否有任何问题,或者是否是效率不高的表结构(至少要快速获取记录)。

【问题讨论】:

  • 查询看起来不正常,您需要从投票而不是产品中进行选择,因为您正在进行计数,其次您需要使用 EXPLAIN select ...(您的查询以查看内容)
  • 感谢您的建议,我会将查询更改为从投票中选择
  • 抱歉,您不需要更改它,但您可以从产品中选择!它应该工作。我误解了这个问题。

标签: php mysql sql inner-join


【解决方案1】:

首先,您的查询很好,尽管我倾向于采用不同的格式:

SELECT p.product_id, p.title, count(*) AS total
FROM products p INNER JOIN
     votes v
     ON v.product_id = p.product_id 
GROUP BY p.product_id 
ORDER BY count(*) DESC
LIMIT 110;

正如另一个答案中提到的,votes(product_id) 上的索引肯定会帮助查询,如果您还没有的话。即使join 的性能有所改进,您仍然有聚合的开销。而且,在 MySQL 中,这可能是很多开销。

如果您期望获得越来越多的选票(达到数百万票),那么您可能不得不采取另一种方法。一种方法是向某个表添加触发器(可能是products 表,它在投票进入时跟踪它们。然后查询会飞。另一种方法是定期汇总数据,类似于使用触发器,但使用的是作业。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-18
    • 2012-05-11
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    相关资源
    最近更新 更多