从后缀表中获取前十名设备

时间:2014-05-02 10:54:29

标签: php mysql

我一直在开发一个应用程序,它显示了系统中存在问题的顶级设备。为此,我创建了一个表格:

---------------------      ---------------------
- equipments_201404 -      - equipments_201405 -
---------------------      ---------------------
- id                -      - id                -
- equipName         -      - equipName         -
- dateTime          -      - dateTime          -
- ...               -      - ...               -
---------------------      ---------------------

这种分离必须与必须存储的数据量有关。因为那,我想知道是否有办法在查询中或通过PHP获得前十名设备。

1 个答案:

答案 0 :(得分:1)

如果您的问题报告少于大约十万个(每月equipments_*个表中的条目,而不是按月将记录拆分为单独的表,或者将表分开,那绝对是一个坏主意.MySQL确实如此。很好地处理包含数十万行的表。很好。认真。

世界上成千上万的成功应用程序在适当大小的MySQL服务器上处理这种大小的数据集。

另一方面,采用分区的系统需要不断维护。

如果您的体验恰恰相反,那是因为您还没有弄清楚如何正确使用索引和查询。我们无法从您的问题中了解您在日常生产中运行的查询类型,因此无法向您提供有关索引的明确建议。话虽这么说,我想在(dateTime,id)上放一个索引是有意义的。

如果你有一张桌子,而不是我建议的每月一张桌子,你可以这样做,让你的十大设备失败。

 SELECT equipName
   FROM equipments
  GROUP BY equipName
  ORDER BY COUNT(*) DESC
  LIMIT 10

如果您想要在当前时间结束的6个月期间排名前十,那么您可以使用此查询。

 SELECT equipName
   FROM equipments
  WHERE dateTime >= NOW() - INTERVAL 6 MONTH 
  GROUP BY equipName
  ORDER BY COUNT(*) DESC
  LIMIT 10

即使对于包含数十万行跨越数十年的数据集,(dateTime, equipName)上的复合索引也会使此查询非常有效。

实际上,您已将数据拆分为月表。以下是您如何处理这些问题的方法。首先:使用一系列UNION ALL操作来创建包含所有数据的虚拟表。如果您的所有月度表都以相同的顺序具有相同的列,那么如果有点无聊则非常容易。

SELECT * FROM equipments_201404 UNION ALL
SELECT * FROM equipments_201403 UNION ALL
SELECT * FROM equipments_201402 UNION ALL
SELECT * FROM equipments_201401 UNION ALL
SELECT * FROM equipments_201312 UNION ALL
SELECT * FROM equipments_201311 UNION ALL
SELECT * FROM equipments_201310 UNION ALL
SELECT * FROM equipments_201309 UNION ALL
SELECT * FROM equipments_201308 UNION ALL
SELECT * FROM equipments_201307 UNION ALL
SELECT * FROM equipments_201306 UNION ALL
SELECT * FROM equipments_201305 UNION ALL
SELECT * FROM equipments_201304   /* etc etc you get the idea */

如果您发出此查询,您将获得所有记录,就好像它们在一个表中一样。然后,您可以将其用作上面显示的查询中的子查询,如下所示。

 SELECT equipName
   FROM (
          SELECT * FROM equipments_201404 UNION ALL
          SELECT * FROM equipments_201403 UNION ALL
          SELECT * FROM equipments_201402 UNION ALL
          SELECT * FROM equipments_201401 UNION ALL
          SELECT * FROM equipments_201312 UNION ALL
          SELECT * FROM equipments_201311 UNION ALL
          SELECT * FROM equipments_201310 UNION ALL
          SELECT * FROM equipments_201309 UNION ALL
          SELECT * FROM equipments_201308 UNION ALL
          SELECT * FROM equipments_201307 UNION ALL
          SELECT * FROM equipments_201306 UNION ALL
          SELECT * FROM equipments_201305 UNION ALL
          SELECT * FROM equipments_201304   /* etc etc you get the idea */
        ) AS equipments
  WHERE dateTime >= NOW() - INTERVAL 6 MONTH 
  GROUP BY equipName
  ORDER BY COUNT(*) DESC
  LIMIT 10

这使您可以假设您的主要摘要查询认为它有一组要处理的统一数据。当然,索引在这里没有多大帮助。

显然,我在六个月的查询中包含了太多的月度表。你可以解决这个问题。但是你每个月都需要修理它。