我有一个 PHP 脚本,它使用 4 个单独的查询从一个 mysql 表中读取最后 25 行(总共 100 行)。
示例:
SELECT * FROM table WHERE datetime <= 'xxx' AND name = 'john' AND category = 'cat1' ORDER BY datetime DESC LIMIT 25
SELECT * FROM table WHERE datetime <= 'xxx' AND name = 'doe' AND category = 'cat1' ORDER BY datetime DESC LIMIT 25
SELECT * FROM table WHERE datetime <= 'xxx' AND name = 'john' AND category = 'cat2' ORDER BY datetime DESC LIMIT 25
SELECT * FROM table WHERE datetime <= 'xxx' AND name = 'doe' AND category = 'cat2' ORDER BY datetime DESC LIMIT 25
我使用4个查询,因为我必须读取不同的记录,基于:name和category,两者都是索引。日期时间也是一个索引。
但是这种方式非常慢(表大约60MB,250K行)。我想知道是否可以通过 1 个查询以更快的方式完成此操作。
编辑mysql表结构
CREATE TABLE IF NOT EXISTS table (
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`datetime` datetime NOT NULL,
`category` varchar(3) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`data1` double NOT NULL,
`data2` double NOT NULL,
`data3` double NOT NULL,
#....
`data50` double NOT NULL,
PRIMARY KEY (`id`),
KEY `datetime` (`datetime`),
KEY `category` (`category`),
KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
如果您想一起运行查询,您可以使用
UNION ALL
将查询结果组合在一起:
(
SELECT *
FROM `table`
WHERE datetime <= 'xxx' AND name = 'john' AND category = 'cat1'
ORDER BY datetime DESC
LIMIT 25
) UNION ALL (
SELECT *
FROM `table`
WHERE datetime <= 'xxx' AND name = 'doe' AND category = 'cat1'
ORDER BY datetime DESC
LIMIT 25
) UNION ALL (
SELECT *
FROM `table`
WHERE datetime <= 'xxx' AND name = 'john' AND category = 'cat2'
ORDER BY datetime DESC
LIMIT 25
) UNION ALL (
SELECT *
FROM `table`
WHERE datetime <= 'xxx' AND name = 'doe' AND category = 'cat2'
ORDER BY datetime DESC
LIMIT 25
)
请注意,由于存在
ORDER BY
和 LIMIT
子句,各个查询需要括在括号中。
添加复合索引:
ALTER TABLE `table` ADD INDEX (category, name, datetime);
您可以删除
category
上的单列索引,因为它是这个新索引中的第一列。