很难提供具体的建议 - 如可能出现的SQL使用 - 不知道更多关于你的架构。不过,我会试试。以下是一些一般性建议。
- 尝试量化“非常缓慢”,这样您就可以知道在改进时是否改进了事物。还要量化您应对的数据量。
- 只使用临时表,如果你确定你需要它们。数据库管理系统中可能发生的最昂贵的(===慢)事件之一是将数据写入表格。如果你不需要临时表,不要使用它们。
- 如果你可以做到这一点,创建一个单一的SQL查询,为您希望从原始数据以HTML显示的表格生成正确的列和行。然后,在命令行mySQL客户端运行该查询,并使用EXPLAIN命令让mySQL告诉你它正在尝试做什么。看到这里:http://dev.mysql.com/doc/refman/5.0/en/explain.html
下面是关于如何查询可能工作的一些更具体的建议。假设你的输入表有这个模式。
vendorname
standard_vendor_name (corrects misspells in vendor name, etc.)
vendor_category (character string)
quarter (integer)
spend (floating point)
比方说,你想要的结果,这些列的表
vendor_category
vendor (standardized spelling)
spend_q1
spend_q2
spend_q3
spend_q4
我很抱歉地说,我不明白你的你是如何处理的供应商名称和类别问题在你的输出中。我假设你只是显示类别,然后为每个供应商命名,然后按类别排序。
我也想不明白你怎么会在你的输入表中存储quarter
。假设您2011年第一季度至2012年第二季度使用20111,201212,20114,2012,2012等数字格式。
假设你想在你的html表格中显示任何四个连续的季度,只是为了微笑。
所以,我们走吧。
我们需要一点点的子查询生成所需的四个季度的ID的基础上,要显示最近一个季度的ID - 您需要提供。
SELECT DISTINCT QUARTER
FROM INFO
WHERE QUARTER <= ~~~the most recent quarter~~~
ORDER BY QUARTER DESC
LIMIT 0,4
如果你总是使用最新的季度开始,你可以简单地从这个小的子查询离开了WHERE QUARTER <= ~~~the most recent quarter~~~
,它会拿起你有最新的数据。
其次,我们需要建立我们的列表的四分之三子查询到一个子查询产生的最近一个季度的数据。
SELECT I.QUARTER, I.VENDOR_CATEGORY, I.STANDARD_VENDOR_NAME, SUM(I.SPEND) SPEND
FROM INFO I
JOIN (
SELECT DISTINCT QUARTER
FROM INFO
WHERE QUARTER <= ~~~the most recent quarter~~~
ORDER BY QUARTER DESC
LIMIT 0,1
) Q ON I.QUARTER=Q.QUARTER
GROUP BY I.QUARTER, I.VENDOR_CATEGORY, I.STANDARD_VENDOR_NAME
这是我们的基本季度查找积木。在这一点上,非常明显的是,您将需要INFO表在QUARTER和VENDOR_CATEGORY列上具有索引。
您可能需要在这两者上或甚至在(QUARTER,VENDOR_CATEGORY,STANDARD_VENDOR_NAME)上使用复合索引。但让事情奏效。然后看看EXPLAIN输出。然后尝试添加其他索引。在你进一步研究之前,有必要摆弄索引来优化这个构建块查询。
我们还需要三个以上的小子查询,每个前一个季度都有一个子查询。除了LIMIT 0,1
,LIMIT 1,1
,LIMIT 3,1
和LIMIT 4,1
以外,子查询与构件块相同。
我们还需要所有需要显示的VENDOR_CATEGORY和STANDARD_VENDOR_NAME组合的主列表。此查询会弹出任何类别/供应商组合的结果,这些结果会在您考虑的任何宿舍中出现一次或多次。
SELECT DISTINCT I.VENDOR_CATEGORY, I.STANDARD_VENDOR_NAME
FROM INFO I
JOIN (
SELECT DISTINCT QUARTER
FROM INFO
WHERE QUARTER <= ~~~the most recent quarter~~~
ORDER BY QUARTER DESC
LIMIT 0,4
) Q ON I.QUARTER=Q.QUARTER
不要做LEFT JOIN在这一块,否则你会与你的所有类别/供应商的项目,包括已在最近四个季度不花钱的那些告终。
现在我们需要把它放在一起。事情变得荒谬冗长(不是SQL的乐趣?)。我们必须一起加入所有这些积木。以下是我们的盛大查询的概要,并带有注释以显示构建模块的位置。
SELECT A.VENDOR_CATEGORY, A.STANDARD_VENDOR_NAME, Q.SPEND, R.SPEND, S.SPEND, T.SPEND
FROM (
/* category combinations */
)A
LEFT JOIN (
/* most recent quarter spend */
)Q ON ( A.VENDOR_CATEGORY=Q.VENDOR_CATEGORY
AND A.STANDARD_VENDOR_NAME=Q.STANDARD_VENDOR_NAME)
LEFT JOIN (
/* second most recent quarter spend */
)R ON ( A.VENDOR_CATEGORY=R.VENDOR_CATEGORY
AND A.STANDARD_VENDOR_NAME=R.STANDARD_VENDOR_NAME)
LEFT JOIN (
/* third most recent quarter spend */
)S ON ( A.VENDOR_CATEGORY=S.VENDOR_CATEGORY
AND A.STANDARD_VENDOR_NAME=S.STANDARD_VENDOR_NAME)
LEFT JOIN (
/* fourth most recent quarter spend */
)T ON ( A.VENDOR_CATEGORY=T.VENDOR_CATEGORY
AND A.STANDARD_VENDOR_NAME=T.STANDARD_VENDOR_NAME)
ORDER BY A.VENDOR_CATEGORY, A.STANDARD_VENDOR_NAME
我会让你把子查询插入到这个大纲中。
您可能已经使用过类似的东西来生成临时表。但是如果你做对了,你可以简单地使用这个大的查询来生成你的报告。除非你的信息表有排列的行数,否则如果你正确地为你的表建立索引,它将会相当快地运行。
如果你拥有行数超越,你可能会为一家大公司工作,这个大公司可以用更快的磁盘和多个千兆字节的RAM来为更大的mySQL服务器发展。这也会加快速度,特别是一旦你编制索引。
我很乐意帮助你,但我需要更多信息。你可以把你实际使用的查询来获取信息吗? – paquettg
+1是一个很好的问题,供您的供应商拼写纠正和“解码器环” –