在我的查询从几秒钟跳到几小时之前,我一直在体验出色的性能。
A) 调查 B) 在 Mysql 上查询过多数据时解决主要的性能瓶颈,我该怎么做?
也许与记忆有关?
结果
在测试存储过程的性能时,我在 5 分钟内运行了两次,首先...
mysql> CALL TopFromBigTable('2012-04-01','2012-05-01',5);
5 rows in set (23.76 sec)
这是非常快的,但后来我再次调用它......我在一个多小时后杀死了它!
mysql> CALL TopFromBigTable('2012-04-01','2012-05-01',5);
---TRANSACTION 1484EF5C, ACTIVE 3571 sec fetching rows, thread declared inside InnoDB 193
mysql tables in use 2, locked 1
MySQL thread id 466174, OS thread handle 0x7f3616ab4700, query id 33098684 localhost root Copying to tmp table
更多测试:
mysql> CALL TopFromBigTable('2012-05-01','2012-05-04',5);
5 rows in set (1.28 sec)
mysql> CALL TopFromBigTable('2012-05-01','2012-05-05',5);
5 rows in set (1.55 sec)
mysql> CALL TopFromBigTable('2012-05-01','2012-05-06',5);
5 rows in set (1 hour 47 min 37.99 sec)
细节
桌子
CREATE TABLE `BigTable` (
`BigTableID` int(11) NOT NULL,
`AnotherID` int(11) NOT NULL,
`Type` char(2) COLLATE utf8_unicode_ci DEFAULT NULL,
`StartTime` datetime NOT NULL,
`EndTime` datetime DEFAULT NULL,
PRIMARY KEY (`BigTableID`),
KEY `Type` (`Type`),
KEY `StartTime` (`StartTime`),
KEY `EndTime` (`EndTime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
查询(注意使这个通用我group by
错了)
CREATE PROCEDURE `TopFromBigTable` (
$StartDate DATETIME,
$EndDate DATETIME,
$ResultLimit INT
)
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT
`Type`,
COUNT(*) AS Count
FROM
`BigTable`
WHERE
`StartTime` > $StartDate
AND
`StartTime` < $EndDate
GROUP BY
`Type`
ORDER BY
Count DESC
LIMIT $ResultLimit
;
COMMIT;
END $$
执行计划
EXPLAIN EXTENDED ...
id: 1
select_type: SIMPLE
table: BigTable
type: range
possible_keys: StartTime
key: StartTime
key_len: 8
ref: NULL
rows: 16446226
filtered: 100.00
Extra: Using where; Using temporary; Using filesort
我在专用报告数据库上运行,因此并非所有正常规则都适用,即我阅读未提交以试图降低开销,因为准确性并不重要,并且该数据库在过去 6 小时内未更新。我想对这实际上有多大帮助(如果有的话)进行基准测试,但我无法可靠地为存储过程计时!