1 个查询选择同一表中不同类别的多行

问题描述 投票:0回答:1

我有一个 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;
mysql select mysqli query-optimization
1个回答
0
投票

如果您想一起运行查询,您可以使用

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
上的单列索引,因为它是这个新索引中的第一列。

© www.soinside.com 2019 - 2024. All rights reserved.