【发布时间】:2012-06-01 12:27:38
【问题描述】:
我有一个表 (MySQL),它有一个名为 binID 的列。此列中的值范围为 1 到 70。
我想要做的是选择该列的唯一值(应该是从 1 到 70 的数字),然后使用每个(我们称之为 theBinID)作为参数将它们迭代到另一个 SELECT 语句中,例如:
SELECT * FROM MyTable WHERE binID = theBinID ORDER BY createdDate DESC LIMIT 10
基本上,我希望为每个 binID 获取 10 个最近的行。
我不相信有一种方法可以用基本的 SQL 语句来做到这一点,虽然我希望这是答案,所以我编写了一个存储过程,它在SELECT DISTINCT 的 binID,然后对其进行迭代并填充临时表。
我的问题是,这是为了优化,如果我获取 100K 行,我得到 1.7 秒的平均时间。执行我的存储过程以获取 700 行(70 个 bin 的 10 条记录)需要 1.4 秒。我意识到 0.3 秒可以被视为相当大的改进,但我希望在 100K 行中获得这个亚秒级。
有没有更好的办法??
完整的存储过程是这样的:
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE binID INT;
DECLARE cur1 CURSOR FOR SELECT DISTINCT heatmapBinID from MEStressTest ORDER BY heatmapBinID ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
DROP TEMPORARY TABLE IF EXISTS TempResults;
CREATE TEMPORARY TABLE TempResults (
`recordID` text NOT NULL,
`queryTerm` text NOT NULL,
`recordCreated` double(11,0) NOT NULL,
`recordByID` text NOT NULL,
`recordByName` text NOT NULL,
`recordText` text NOT NULL,
`recordSource` text NOT NULL,
`rerecordCount` int(11) NOT NULL DEFAULT '0',
`timecodeOffset` int(11) NOT NULL DEFAULT '-1',
`recordByImageURL` text NOT NULL,
`canDelete` int(11) NOT NULL DEFAULT '1',
`heatmapBinID` int(11) DEFAULT NULL,
`timelineBinID` int(11) DEFAULT NULL,
PRIMARY KEY (`recordID`(20))
);
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO binID;
IF done THEN
LEAVE read_loop;
END IF;
INSERT INTO TempResults (recordID, queryTerm, recordCreated, recordByID, recordByName, recordText, recordSource, rerecordCount, timecodeOffset, recordByImageURL, canDelete, heatmapBinID, timelineBinID)
SELECT * FROM MEStressTest WHERE heatmapBinID = binID ORDER BY recordCreated DESC LIMIT numRecordsPerBin;
END LOOP;
CLOSE cur1;
SELECT * FROM TempResults ORDER BY heatmapBinID ASC, recordCreated DESC;
结束
【问题讨论】:
标签: mysql stored-procedures query-optimization